SQL Server 中 MIN/MAX 的更快替代方案

Posted

技术标签:

【中文标题】SQL Server 中 MIN/MAX 的更快替代方案【英文标题】:Faster alternative of MIN/MAX in SQL Server 【发布时间】:2020-11-30 12:22:15 【问题描述】:

我需要过去 n 天的最低/最高股票价格。以下查询的工作速度非常慢。我将不胜感激更快的替代方案:

SELECT 
    *, 
    MIN(Close) OVER (PARTITION BY Ticker ORDER BY PriceDate ROWS BETWEEN 14 PRECEDING AND 1 PRECEDING) AS MinPrice14d,
    MAX(Close) OVER (PARTITION BY Ticker ORDER BY PriceDate ROWS BETWEEN 14 PRECEDING AND 1 PRECEDING) AS MaxPrice14d
FROM
    (SELECT CompanyID, Ticker, PriceDate, Close            
     FROM price.PriceHistoryDaily) a
我需要指定的列。 它在尾随,所以我每天都需要它。 至于期限,我会限制在一年以内。

【问题讨论】:

请定义“非常慢”和“更快的替代方案”。这些条款对基于意见的解释开放...... 慢到超过 20 分钟。我需要将其限制在至少 10 分钟 请显示表模式和当前执行计划。 这很慢,因为您在历史记录表中选择每一行,然后计算每行的最小值/最大值。限制您在外部查询中选择的行(由于没有特殊原因,这过于复杂)或添加索引。随着行数的增加,性能只会随着时间的推移而下降(命名为“历史”)。 表中的所有行都需要这个吗?你需要在你的表中每行一行吗?你需要所有的列吗? 【参考方案1】:

虽然不影响性能,但也不需要子查询。所以从更简单的版本开始:

SELECT phd.CompanyID, phd.Ticker, phd.PriceDate, phd.Close,
       min(Close) over (partition by Ticker
                        order by PriceDate
                        rows between 14 preceding and 1 preceding
                       ) as MinPrice14d,
       max(Close) over (partition by Ticker
                        order by PriceDate
                        rows between 14 preceding and 1 preceding
                       ) as MaxPrice14d
FROM price.PriceHistoryDaily phd;

然后尝试添加索引:PriceHistoryDaily(Ticker, PriceDate)

注意:这会返回来自PriceHistoryDaily所有 行,并且 - 根据表的大小 - 这可能是推动性能的原因。

【讨论】:

好吧,我不这样做,因为我会在另一个公式中使用这些值。 至于索引。你能举个例子吗?我需要创建临时表。 @Yana 。 . .由于某些公式,您不会使用索引?我不明白你的评论。 对不起。我使用了子查询,而不是您的简单版本,因为整个查询将成为另一个查询的一部分,我将使用 MinPrice14d 和 MaxPrice14d 作为公式中的变量。 @Yana 。 . .您可以对子查询使用相同的索引。

以上是关于SQL Server 中 MIN/MAX 的更快替代方案的主要内容,如果未能解决你的问题,请参考以下文章

SQL min() max() 函数异常

sql MIN()MAX()

LINQ to SQL语句Count/Sum/Min/Max/Avg操作符

LINQ to SQL语句之Select/Distinct和Count/Sum/Min/Max/Avg (转)

SQL SERVER,使用(TABLOCKX)选择查询会比使用(NOLOCK)更快,反之亦然?

为啥 MS-Access 中的 Teradata 查询比 SQL Server 更快