3

Context 是 Oracle Database,Entity Framework 5,LinqToEntities,Database First。

我正在尝试在一些大表上实现分页,我的 linqToEntities 查询如下所示:

context.MyDbSet
    .Include("T2")
    .Include("T3")
    .Include("T4")
    .Include("T5")
    .Include("T6")
    .Where(o => o.T3 != null)
    .OrderBy(o => o.Id)
    .Skip(16300)
    .Take(50);

事实是,取决于我想跳过多少条记录(0 或 16300),它从 0.08 秒到 10.7 秒。

这对我来说似乎很奇怪,所以我检查了生成的 SQL,它是这样的:

SELECT * 
FROM ( 
SELECT 
[...]
FROM ( SELECT [...] row_number() OVER (ORDER BY "Extent1"."Id" ASC) AS "row_number"
    FROM      T1 "Extent1"
    LEFT OUTER JOIN T2 "Extent2" ON [...]
    LEFT OUTER JOIN T3 "Extent3" ON [...]
    LEFT OUTER JOIN T4 "Extent4" ON [...]
    LEFT OUTER JOIN T5 "Extent5" ON [...]
    LEFT OUTER JOIN T6 "Extent6" ON [...]
    WHERE ("Extent1"."SomeId" IS NOT NULL)
)  "Filter1"
WHERE ("Filter1"."row_number" > 16300)
ORDER BY "Filter1"."Id" ASC
)
WHERE (ROWNUM <= (50) )

我检查了是否真的是 Oracle 通过 SQL Developper 花费了时间,并且确实如此。

然后我检查了执行计划,它出现了:

执行计划

我真正理解的是,对于 row_number 的第一个过滤器没有 STOPKEY,它可能会获取整个子查询。

我真的不知道在哪里看,如果我没记错的话,请求是由 ODT/ODP/.. 生成的,因此,应该针对 Oracle DB 进行优化.. (我自己无法更改) )

也许我的数据库模型已经烂了,我可以添加任何索引或优化以使其更好地工作?

4

1 回答 1

2

你看到所有那些 UNIQUE SCAN 子查询了吗?这在每一张桌子上都是独一无二的。

您应该与作为父级的 T1 具有一对多关系,并且您需要在查询中的任何表都与 T1 上FOREIGN KEY的索引 ID 主键列建立关系。

然后你可以使用Join代替,Include子查询将是不必要的。

于 2014-01-22T19:14:08.353 回答