bsara
bsara

Reputation: 8249

Oracle query using Entity Framework is ridiculously slow

Here is my setup:

So here's my problem: I have some entities that I've created with Oracle Developer Tools for Visual Studio (11.2.0.3.20). Some of the entities return results fairly quickly. However, with others that are querying against a view/table that contains more than 20 million records, it is consistently taking 10 minutes to return results (I've verified this time via unit tests) for this simple query:

var member = (from m in context.Members
              where m.MemberID.Equals(memberId, StringComparison.OrdinalIgnoreCase)
              select m).FirstOrDefault();

I used to be using Devart dotConnect for Oracle which worked really well...but my company isn't renewing their license for this product and have told me to use the new Oracle Developer Tools for Visual Studio to accomplish things.

As a work around, I've made a direct connection to the database using OracleCommand provided by ODP.NET (Oracle.DataAccess.dll) and I get results back in less than a second. Same with doing other queries directly against the database using a management client.

My best guess as to why this is happening would be that perhaps Entity is loading the entire database into memory and then running my queries on it...which would be horrible, but I really don't believe that is what is happening.

Can someone please explain why this is happening and how I can fix it using Entity so that I don't have to manually rewrite all of my DB queries?


UPDATE:
So I found the reason that my queries were taking 10 minutes to complete. I (with my very little experience with databases) had put this in my EDMX file:

...
<EntityContainer Name="MyStoreContainer">
  <EntitySet Name="MY_TABLE" EntityType="MyDB.Store.MY_TABLE" store:Type="Views" store:Schema="MYUSERNAME" store:Name="MY_TABLE">
    <DefiningQuery>
      SELECT
      "MY_TABLE"."COL1" AS "COL1",
      "MY_TABLE"."COL2" AS "COL2",
      "MY_TABLE"."COL3" AS "COL3",
      "MY_TABLE"."COL4" AS "COL4",
      "MY_TABLE"."COL5" AS "COL5",
      "MY_TABLE"."COL6" AS "COL6",
      "MY_TABLE"."MEMBERSHIP_ID" AS "MEMBERSHIP_ID",
      "MEMBERS"."EXTRA_INFO1" AS "EXTRA_INFO1",
      "MEMBERS"."EXTRA_INFO2" AS "EXTRA_INFO2"
      FROM "MYUSERNAME"."MY_TABLE" "MY_TABLE"
      LEFT JOIN "MYUSERNAME"."MEMBERS" ON "MY_TABLE"."MEMBERSHIP_ID" = "MEMBERS"."MEMBER_ID"
    </DefiningQuery>
  </EntitySet>
...

Turns out that the LEFT JOIN takes about 10 minutes when directly querying with a management client as well. So I took the LEFT JOIN out...and now I see an increase in speed. Here's the catch, this EntitySet was NOT the EntitySet that I was querying against when I was getting really slow responses. I still get a response about 4-5 times faster if I manually write the code with OracleCommand.
Can anyone explain why Entity is slowing things down so much and when I am not even accessing this left join query?

Upvotes: 7

Views: 8556

Answers (4)

pravi
pravi

Reputation: 175

We had a similar performance issue. Thanks @CameronP for the suggestion to use the EntityFunctions.AsNonUnicode, which fixed the performance issue. Our project uses EF6 with Oracle 12.1* Managed Data Access. Instead of making the change to every EF query parameter, we used the TypeName attribute on the Entity Model and it worked !

Public Class Table1
    <Column("COLUMN_1", TypeName:="VARCHAR2")>
    Public Property Column1 As String
End Class 

Upvotes: 2

An other solution is to update your oracle provider! Odac 12c fix this problem : https://community.oracle.com/message/11065799#11065799

It will prevent you from changing all your query with EntityFunctions.AsNonUnicode()

Upvotes: 1

Luis Antonio Pestana
Luis Antonio Pestana

Reputation: 1009

Another trick is to disable Lazy Loading.

If you can disable, do it.

Example when you can't disable Lazy Loading:

When you have a table called Customers. Then, when you call something like this:

var obj = myCustomerList.FirstOrDefault().ORDERS.ToList()

If you have code that access childrens, you can't disable the Lazy Loading

Upvotes: -2

CameronP
CameronP

Reputation: 305

Wrap your input parameter with EntityFunctions.AsNonUnicode(memberId).

var member = (from m in context.Members
          where m.MemberID.Equals(EntityFunctions.AsNonUnicode(memberId), StringComparison.OrdinalIgnoreCase)
          select m).FirstOrDefault();

See https://community.oracle.com/message/10725648

Upvotes: 6

Related Questions