按顺序选择前4名,但仅在实际需要时选择?

时间:2013-10-29 14:18:44

标签: sql sql-server

我有一个存储过程的一部分,被称为成千上万次,因此占据了整个事情的大部分。通过执行计划运行它看起来像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的执行计划 Execution Plan 1

插入和假脱机的故障: Breakdowns

然后选择top4和orderby的执行计划: Execution Plan2

如果需要进一步的信息或细分,请告诉我,#Mympmptable的大小通常为28000行且有索引

CREATE INDEX MyIndex on #MyTempTable (Param1, Param2) INCLUDE ([SomeField])

1 个答案:

答案 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