更新:我错误关于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
答案 0 :(得分:2)
是的,您可以自己查询。
db.SqlQuery<something>("SELECT * FROM x ...");