我有一个存储过程的一部分,被称为成千上万次,因此占据了整个事情的大部分。通过执行计划运行它看起来像TOP 4和Order By部分占用了很多。订单使用的函数尽管精简了,但仍然会被使用一段时间。
这是一个奇怪的情况,因为对于99.5%的数据,无论如何都会返回4个或更少的结果,它只需要0.5%的时间我们需要TOP 4.这是数据算法的要求所以完全取消TOP 4不是一种选择。
所以我要说我的语法是
SELECT SomeField * SomeOtherField as MainField, SomeOtherField
FROM
(
SELECT TOP 4
SomeField, 1/dbo.[Myfunction](Param1, Param2, 34892) as SomeOtherField
FROM #MytempTable
WHERE
Param1 > @NextMargin1 AND Param1 < @NextMargin1End
AND Param2 > @NextMargin2 AND Param2 < @NextMargin2End
ORDER BY dbo.[MyFunction](Param1, Param2, 34892)
) d
有没有办法告诉SQL服务器按以下方式执行订单?当且仅当在发生的地方后返回的结果超过4时?否则我不需要订单。也许是表变量和if?
中表的计数---基于戴维斯答案的更新,试图弄清楚为什么它变慢:
我做了检查,可以确认96.5%的时间有4个或更少的结果,所以不是数据超出预期的情况。
以下是插入@FunctionResults的执行计划
插入和假脱机的故障:
然后选择top4和orderby的执行计划:
如果需要进一步的信息或细分,请告诉我,#Mympmptable的大小通常为28000行且有索引
CREATE INDEX MyIndex on #MyTempTable (Param1, Param2) INCLUDE ([SomeField])
答案 0 :(得分:2)
此答案已根据提问者的持续反馈进行了更新。最初的建议是尝试使用表变量来存储预计算并从结果中选择前4位。但是,在实践中,似乎优化器过高估计了行数并选择了错误的执行计划。
除了之前的建议之外,我还建议在对此过程进行任何更改后定期更新统计信息,以便为查询优化器提供更新的信息,以便做出更明智的决策。
由于这是一个无法直接访问源环境的性能调优过程,因此预计此答案将根据用户反馈进行更改。根据上面@SteveFord的建议,下面的示例查询反映了使用CROSS APPLY来尝试避免多次不必要的函数调用。
SELECT TOP 4
M.SomeField,
M.SomeField * 1/F.FunctionResults [SomeOtherField]
FROM #MytempTable M
CROSS APPLY (SELECT dbo.Myfunction(M.Param1, M.Param2, 34892)) F(FunctionResults)
ORDER BY F.FunctionResults