Mik*_*ila 4 oracle performance entity-framework repository-pattern
我对Entity Framework 5和Oracle DB存在性能问题.
我有一个简单的SQL选择: SELECT * FROM NOTE WHERE NOTENUMBER = '1A23456'
NOTENUMBER
包含在名为NOTE的表的索引中,但该字段不是主键/唯一.
当我使用Oracle SQL Developer执行语句时,结果很快返回,查询计划显示正在使用RANGE SCAN.
当我使用Entity Framework时,生成的SQL需要更长的时间(5秒对30ms).
当我使用Entity Framework并使用主键字段(NOTE_KEY)进行查询时,结果会像SQL Developer一样快速返回.
我怀疑有两件事:
EF和Oracle.DataAccess-provider存在一些问题,没有使用可用的非唯一索引.如果我有Entity Framework 5的调试符号会有所帮助,但我无法在任何地方找到它们.
性能问题在EF的某个地方,关于闭包和/或我在EF中使用通用存储库模式的方式:
如果我像这样调用我的存储库:
var notenumber = "1A23456";
var notes = repository.All(n => n.NOTENUMBER == notenumber).ToList();
谓词在方法All
中出现:
{n => (n.NOTE == value(Tester.Program+<>c__DisplayClass0).notenumber)}
并且EfProf-profiler将生成的SQL跟踪为:
SELECT "Extent1"."NOTE_KEY" AS "NOTE_KEY",
"Extent1"."NOTENUMBER" AS "NOTENUMBER",
"Extent1"."NOTETEXT" AS "NOTETEXT",
FROM "NOTE_DBA"."NOTE" "Extent1"
WHERE ("Extent1"."NOTENUMBER" = '1PSA0500237500' /* @p__linq__0 */)
查询需要大约5500毫秒.
另一方面,如果我像这样调用我的存储库:
var notes = repository.All(n => n.NOTENUMBER == "1A23456").ToList();
然后谓词出现为:
{n => (n.NOTENUMBER == "1A23456")}
并且EfProf-profiler将生成的SQL跟踪为:
SELECT "Extent1"."NOTE_KEY" AS "NOTE_KEY",
"Extent1"."NOTENUMBER" AS "NOTENUMBER",
"Extent1"."NOTETEXT" AS "NOTETEXT",
FROM "NOTE_DBA"."NOTE" "Extent1"
WHERE ('1PSA0500237500' = "Extent1"."NOTENUMBER")
查询需要大约30ms.
所以唯一的区别是WHERE子句中条件的顺序,以及后者似乎没有EF替换参数的事实.
我使用VS2010和.NET4,并参考EF5(v4.4.0.0).存储库的All-method是:
public IQueryable<NOTE> All(Expression<Func<NOTE, bool>> predicate = null)
{
var setOfNotes = GetDbSet<NOTE>();
var notesQuery = from note in setOfNotes select note;
if (predicate != null)
{
notesQuery = notesQuery.Where(predicate);
}
return notesQuery;
}
Run Code Online (Sandbox Code Playgroud)
我试图创建一个CompiledQuery,我尝试使用setOfNotes.AsNoTracking()
,我试图以.NET 4.5为目标 - 性能没有差别.
我能够快速获得这个特定查询的一种方法是使用Oracle的基本.NET数据提供程序(ODB.NET)并手动构建查询,但我宁愿不坚持使用该解决方案.同样,如果我在where子句中使用主要字段,即使使用EF和相同的All-method,查询也很快.
所以问题似乎在EF的某个地方.如果我只有EntityFramework.dll的符号,我觉得可以找到更多.
EF调用谓词的方式会有问题吗?如何在EF中替换'@p_ linq _0 ' 参数?
小智 5
我遇到了类似的问题.在我的情况下没有使用索引的原因是我从.NET传递一个字符串(unicode)作为参数.将其与非unicode数据库字段进行比较.
解决方案是在将字符串参数传递给非unicode之前将其传递给where子句:
using System.Data.Objects;
EntityFunctions.AsNonUnicode( myUnicodeParam)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1950 次 |
最近记录: |