Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Oracle query using Entity Framework is ridiculously slow

Here is my setup:

  • Compiling at .NET 4.0 (I can't go any higher than this)
  • Using EntityFramework against Oracle 11gR2 database
  • Using ODP.NET 11.2.0.3.20
  • Using Visual Studio 2012 Ultimate and Oracle Developer Tools for Visual Studio 11.2.0.3.20
  • Performing queries using LINQ to Entity

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?

like image 735
bsara Avatar asked Feb 14 '13 23:02

bsara


2 Answers

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

like image 88
CameronP Avatar answered Sep 29 '22 11:09

CameronP


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 
like image 26
pravi Avatar answered Sep 29 '22 11:09

pravi