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 进行优化.. (我自己无法更改) )
也许我的数据库模型已经烂了,我可以添加任何索引或优化以使其更好地工作?