You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL查询SELECT下调用存储函数过慢,如何内嵌逻辑替代优化?

问题解决方案

性能问题根因

  • 你使用的是标量自定义函数,SQL Server执行这类函数时会逐行触发调用:每处理Table1的1行数据,就要单独执行2次Table2的查询求最小时间,数据量较大时会产生极多重复查询开销,这就是耗时飙升的核心原因。

优化方案:直接嵌入逻辑消除函数调用

不需要保留存储函数,我们可以把判断逻辑转化为OUTER APPLY关联查询,一次计算所有需要的判断结果,改写后的完整查询如下:

USE defaultDB;
GO

SELECT 
    M.[Stime], 
    M.[Etime],
    T.[target],
    C.[CL],
    [WinRate] = COUNT(CASE WHEN M.[Max] > T.[target] THEN 1 END)  / CAST(COUNT(*) AS FLOAT),
    [E] = AVG(CASE 
        WHEN M.[Max] >= T.[target] AND M.[Min] < C.[CL] THEN IIF(ISNULL(HF.first_high_time, 999999) <= ISNULL(HF.first_low_time, 999999), T.[target], C.[CL])         
        WHEN M.[Max] >= T.[target] AND M.[Min] > C.[CL] THEN T.[target]  /* 仅命中高点 */
        WHEN M.[Max] < T.[target] AND M.[Min] < C.[CL] THEN C.[CL] /* 仅命中止损 */
        WHEN M.[Max] < T.[target] AND M.[Min] > C.[CL] THEN M.[EndReturn] /* 两者都未命中 */
    END),
    [count] = COUNT(*)
FROM [defaultDB].[dbo].[Table1] M
-- 目标收益率枚举
JOIN (VALUES (0.003), (0.0035), (0.004), (0.0045), (0.005), (0.0055), (0.006), (0.0065), (0.007), (0.0075), (0.008)) AS T([target])  
    ON 1 = 1
-- 止损率枚举
JOIN (VALUES (-0.003), (-0.0035), (-0.004), (-0.0045), (-0.005), (-0.0055), (-0.006), (-0.0065), (-0.007), (-0.0075), (-0.008), (-0.0085), (-0.009), (-0.0095), (-0.01), (-0.0105), (-0.011), (-0.0115)) AS C([CL]) 
    ON 1=1
-- 替代原函数的关联查询,一次计算当前行对应的高低点首次触发时间
OUTER APPLY (
    SELECT 
        MIN(CASE WHEN [H] > T.[target] THEN [time] END) AS first_high_time,
        MIN(CASE WHEN [L] < C.[CL] THEN [time] END) AS first_low_time
    FROM [defaultDB].[dbo].[Table2]
    WHERE [date] = M.[date] 
        AND [Start] >= M.[Stime] 
        AND [Time] <= M.[Etime]
) HF
WHERE M.[date] IN (20120307,20120601,20121109,20130826,20131002,20140117,20140122,20140311,20140529,20140718,20150619,20151014,20151022,20160411,20160516,20160721,20160818,20160909,20170127,20170213,20170921,20171025,20171229,20180116,20180315,20180926,20181022,20181128,20181211,20190104,20190329,20190502,20190521,20190528,20190611,20190627,20190823,20190930,20191104,20191211,20200214,20200318,20200529,20200706,20200828,20201230,20210112,20210305,20210318,20210408,20210525,20210617,20210625)
    AND M.[Stime] >= 133000  
GROUP BY M.[Stime], M.[Etime], T.[Target], C.[CL]

如果需要进一步提升查询速度,可以给Table2创建联合索引,降低关联查询的IO开销:

CREATE NONCLUSTERED INDEX IX_Table2_DateStart ON Table2 ([date], [Start]) INCLUDE ([Time], [H], [L])

内容的提问来源于stack exchange,提问作者Chow Stanley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 13:15:03