【问题标题】:RowNumber() and Partition By performance help wantedRowNumber() 和 Partition By 性能需要帮助
【发布时间】:2012-08-24 22:28:51
【问题描述】:

我有一个股市移动平均值表,我试图比较一天内的两个值,然后将该值与前一天的相同计算值进行比较。我的 sql 如下所示......当我注释掉定义结果集的最后一个 select 语句并运行显示为结果集的最后一个 cte 时,我在大约 15 分钟内取回了我的数据。长,但易于管理,因为它会在一夜之间作为插入 sproc 运行。当我如图所示运行它时,我在任何结果开始出现之前的 40 分钟。有什么想法吗?它从有点慢到爆炸,可能是添加了ROW_NUMBER() OVER (PARTITION BY) BTW 我仍在研究逻辑,这对于这个性能问题目前是不可能的。提前谢谢..

编辑:我按照以下建议修复了我的分区。

with initialSmas as
(
    select TradeDate, Symbol, Period, Value
    from tblDailySMA
),

smaComparisonsByPer as
(
    select i.TradeDate, i.Symbol, i.Period FastPer, i.Value FastVal, 
        i2.Period SlowPer, i2.Value SlowVal, (i.Value-i2.Value) FastMinusSlow
    from initialSmas i join initialSmas as i2 on i.Symbol = i2.Symbol 
        and i.TradeDate = i2.TradeDate and i2.Period > i.Period
),

smaComparisonsByPerPartitioned as
(
    select ROW_NUMBER() OVER (PARTITION BY sma.Symbol, sma.FastPer, sma.SlowPer
    ORDER BY sma.TradeDate) as RowNum, sma.TradeDate, sma.Symbol, sma.FastPer,
    sma.FastVal, sma.SlowPer, sma.SlowVal, sma.FastMinusSlow
    from smaComparisonsByPer sma
)

select scp.TradeDate as LatestDate, scp.FastPer, scp.FastVal, scp.SlowPer, scp.SlowVal,
    scp.FastMinusSlow, scp2.TradeDate as LatestDate, scp2.FastPer, scp2.FastVal, scp2.SlowPer, 
    scp2.SlowVal, scp2.FastMinusSlow, (scp.FastMinusSlow * scp2.FastMinusSlow) as Comparison
from smaComparisonsByPerPartitioned scp join smaComparisonsByPerPartitioned scp2
on scp.Symbol = scp2.Symbol and scp.RowNum = (scp2.RowNum - 1)

【问题讨论】:

  • 执行计划是什么,表上有索引吗?
  • 自引用 CTE 很慢。使用临时表。 stackoverflow.com/a/2741802/284240
  • 我的表上确实有一个唯一的聚集索引。我把它放到数据库引擎优化顾问那里,它没有给出任何建议。你想要执行计划 xml 吗?
  • 第一个 CTE 并没有真正的帮助。 “期”是什么意思?如果不理解“句号”,就很难完整地理解第二个 CTE。我的个人偏好:当我将一个表加入自身时,我通常使用LR 作为别名(“左”和“右”)或在别名前加上“L”和“R”,例如LsmaCBPRsmaCBP。如果连接有一些特定的语义原因,那么我将使用它,例如ParentOrganismChildOrganism.
  • @HABO 谢谢。 “周期”是描述移动平均值的天数、5、10、20 等。如果有帮助的话。

标签: sql-server sql-server-2008 sql-server-2008-r2 query-performance


【解决方案1】:

1) 您在 Partition By 和 Order By 子句中都有一些字段。这是没有意义的,因为每个(sma.FastPer、sma.SlowPer)都只有一个值。您可以从窗口函数的 Order By 部分安全地删除这些字段。

2) 假设您已经在“initialSmas i join initialSmas”中拥有足够性能的索引,并且您已经拥有 (initialSmas.Symbol, initialSmas.Period, initialSmas.TradeDate) 的索引,那么您可以做的最好的事情就是复制smaComparisonsByPer 到一个临时表中,您可以在其中创建索引 (sma.Symbol, sma.FastPer, sma.SlowPer, sma.TradeDate)

【讨论】:

  • 谢谢...很好,我修复了分区,就像我说的那样我还在粗略的逻辑..
猜你喜欢
  • 2017-07-14
  • 2020-07-23
  • 1970-01-01
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
  • 2011-04-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多