Reputation: 8249
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
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
Reputation: 121
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
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
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