【问题标题】:Indexes are not working in entity framework索引在实体框架中不起作用
【发布时间】:2014-05-20 10:59:23
【问题描述】:

我在我的项目中使用了实体框架(在 .Net 中使用 MVC)并使用 Oracle 作为数据库。

一张表中有大量数据(数百万条记录)。 而且很多列都有索引。

当我使用上面的带有多个条件的 where 子句从视图中访问数据时,然后它会快速执行。但是我在使用实体框架的代码中使用相同的 where 子句,那么它需要很长时间(可能是 10-15 分钟)。

索引与实体框架有关系吗?

实体框架不支持索引?

LINQ 生成的查询:

SELECT 
CAST( "Extent1"."LOPNR1" AS number(9,0)) AS "C1", 
CAST( "Extent1"."LOPNR2" AS number(9,0)) AS "C2", 
CAST( "Extent1"."INTFTG" AS number(9,0)) AS "C3", 
"Extent1"."LON" AS "LON", 
"Extent1"."EZX" AS "EZX", 
"Extent1"."FAKTNR" AS "FAKTNR", 
 ...........................

 CAST( "Extent1"."UTBETDAT" AS number(9,0)) AS "C11", 
 CAST( "Extent1"."INBETDAT" AS number(9,0)) AS "C12", 
"Extent1"."TRANSTEXT" AS "TRANSTEXT", 
"Extent1"."ANVFRITT" AS "ANVFRITT", 
 CAST( "Extent1"."FLAGGA3" AS number(4,0)) AS "C13", 
 CAST( "Extent1"."FLAGGA4" AS number(4,0)) AS "C14", 
 CAST( "Extent1"."FLAGGA5" AS number(4,0)) AS "C15", 
 CAST( "Extent1"."DATUPPDAT" AS number(9,0)) AS "C16", 
.......... 
"Extent1"."TRI" AS "TRI", 
 CAST( "Extent1"."OBJIDNR" AS number(18,0)) AS "C17", 
 CAST( "Extent1"."DOKLOPNR" AS number(18,0)) AS "C18", 
.............................
 CAST( "Extent1"."FULLDATE" AS number(18,0)) AS "C30", 
"Extent1"."RADID" AS "RADID", 

"Extent1"."INTFTG_VIEW" AS "INTFTG_VIEW", 
 CAST( "Extent1"."ISOBJECT" AS number(18,0)) AS "C31"
FROM (SELECT 
  "ViewName"."LOPNR1" AS "LOPNR1", 
  "ViewName"."LOPNR2" AS "LOPNR2", 
  "ViewName"."INTFTG" AS "INTFTG", 
  .....................................
  "ViewName"."BOKFDAG_VIEW" AS "BOKFDAG_VIEW", 
  "ViewName"."INTFTG_VIEW" AS "INTFTG_VIEW", 
  "ViewName"."ISOBJECT" AS "ISOBJECT"
  FROM "SchemaName"."ViewName" ) "Extent1"
WHERE ((3 <> ( CAST(  CAST( "Extent1"."FLAGGA3" AS number(4,0)) AS number(9,0)))) AND                (9 <> ( CAST(  CAST( "Extent1"."FLAGGA4" AS number(4,0)) AS number(9,0)))) AND     ("Extent1"."BOKFBEL" > 0) AND (1 = 1) AND (1 = 1) AND (1 = 1) AND (1 = 1) AND (1 = 1) AND (1 = 1) AND (1 = 1) AND (1 = 1) AND (1 = 1) AND (3636002 = ( CAST( "Extent1"."INTFTG" AS number(9,0)))) AND (90 = ( CAST(  CAST( "Extent1"."VTYP" AS number(4,0)) AS number(9,0))))    AND (1 = 1))

【问题讨论】:

  • 因为实体框架只是执行 SQL 查询,并且索引应用在数据库级别,那么实体框架不应该关心索引。但这可能是实体框架方面的 Oracle 提供商的一个问题。您可以发布用于查询这些数据的实体框架代码吗?也许它会重复查询?
  • 如果可能的话,LINQ 查询也会有所帮助。
  • 我的屏幕是搜索/结果类型,where 子句字符串是动态创建并附加在 LINQ where 子句中
  • 尝试以小数形式提供搜索参数。

标签: database oracle entity-framework


【解决方案1】:

您的代码不能使用任何索引。假设您在 Extent1.FLAGGA3 上有一个索引。 Oracle 查看您的 WHERE 子句并查看

 CAST(Extent1.FLAGGA3, ...) <> 3

如果是的话

Extent1.FLAGGA3 <> 3

那么可以使用索引,但是当列上有一个函数时,为了使用索引,Oracle需要将该函数应用于索引中的每个键。这很可能是相当昂贵的,Oracle 选择不使用该索引。

为什么需要所有 CAST?

看起来 CAST 问题的一般解决方案是使用包含而不是 =, 来自答案之一的 cntr-V:

short[] shortValue = new short[] { 6 };
var entityList = from r in rep.DataContext.FooTable
--where r.SmallIntColumn == shortValue
where shortValue.Contains(r.SmallIntColumn)
select r;

【讨论】:

  • 实际上 CAST 是由实体框架完成的,因为在 Oracle 中它的编号为 number(10,0) 所以,在模型中(在代码中)我使用 Int32。
  • 你能要求不要这样做吗?您比较 2 个数字,为​​什么需要将其中一个从 number(4) 转换为 number(9)?你实际上必须杀死那个演员。我看到这是一个常见问题:blog.hompus.nl/2013/01/21/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-28
  • 2017-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多