强制EF“子查询”中的“TOP 100 PERCENT”可查询

时间:2015-04-01 19:11:27

标签: linq entity-framework sql-server-2005 entity-framework-4 linq-to-entities

更新:错误关于top 100 percent生成更好的查询计划(对于合理规模的top N,该计划仍然要好得多,并且可能与参数嗅探有关。)

虽然我仍然认为这个有针对性的问题具有优点,但它并不是一个有用的解决方案"对于我的问题 2 ,可能不适合你..


我遇到了一些SQL Server优化不佳的查询。统计信息显示正确,SQL Server选择更糟糕的'即使估计值和实际值相同,也会对百万记录执行搜索的计划 - 但这个问题关于 1

在有问题的查询中有简化形式:

select * from x
join y on ..
join z on ..
where z.q = ..

然而(因为我知道基数更好,显然)以下形式一致导致很多更好的查询计划:

select * from x
join (
  -- the result set here is 'quite small'
  select top 100 percent *
  from y on ..
  join z on ..
  where z.q = ..) t on ..

在L2S中,Take功能可用于限制top N,但问题是"我有这种方法是需要一个有限/固定N,这样一些查询可以假设只是破坏,而不是只是强制实现运行真的很慢。

虽然我可以选择一个非常大的'具有讽刺意味的是top N这个值(对于初始问题),随着N的值增加,SQL查询执行时间增加。预期的中间结果预计只有几十到几百条记录。我当前的代码运行top 100然后,如果检测到包含太多结果,则再次运行查询而没有限制:但这感觉就像一个kludge ..在kludge之上。

问题是:EF / L2E / LINQ查询是否可以在 EF Queryable 上生成等效的top 100 percent

(通过ToList强制实现不是一个选项,因为结果应该是 EF Queryable 并保留在LINQ to Entities中,而不是LINQ to Objects。)

虽然我目前正在处理EF4,但如果在以后的EF版本中[仅]可以这样做接受,例如答案 - 这是有用的知识并且确实回答了问题。


1 如果希望回答"不要这样做"或者替代",请将其作为次要答案,或者在沿旁边,并回答所询问的实际问题。否则,请随意使用评论。


2 top 100 percent没有生成更好的查询计划外,我忘了列出核心问题'岌岌可危,这是一个糟糕的参数嗅探(实例是SQL Server 2005)。

以下查询需要很长时间才能完成,而直接变量替换在眨眼之间运行""指示参数嗅探的问题。

declare @x int
set @x = 19348659

select
op.*
from OrderElement oe
join OrderRatePlan rp on oe.OrdersElementID = rp.OrdersElementID
join OrderPrice op on rp.OrdersRatePlanID = op.OrdersRatePlanID
where oe.OrdersProductID = @x

kludged-but-workable查询

select
  op.*
from OrderPrice op
join (
  -- Choosing a 'small value of N' runs fast and it slows down as the
  -- value of N is increases where N >> 1000 simply "takes too long".
  -- Using TOP 100 PERCENT also "takes too long".
  select top 100
    rp.*
  from OrderElement oe
  join OrderRatePlan rp on oe.OrdersElementID = rp.OrdersElementID
  where oe.OrdersProductID = @x
) rp
on rp.OrdersRatePlanID = op.OrdersRatePlanID

1 个答案:

答案 0 :(得分:2)

是的,您可以自己查询。

db.SqlQuery<something>("SELECT * FROM x ...");