我有一张股票市场移动平均值表,我试图比较一天内的两个值,然后将该值与前一天的相同计算值进行比较。我的 sql 如下...当我注释掉定义结果集的最后一个 select 语句,并运行显示为结果集的最后一个 cte 时,我会在大约 15 分钟内取回数据。很长,但易于管理,因为它将作为插入存储过程运行过夜。当我如图所示运行它时,我还需要 40 分钟才能得到任何结果。有什么想法吗?它从有点慢到爆炸,可能还加上了顺便说ROW_NUMBER() OVER (PARTITION BY)
一句,我仍在研究逻辑,目前在这个性能问题上这是不可能的。提前致谢..
编辑:我按照下面的建议修复了我的分区。
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)
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)
执行计划是什么?表上有索引吗?
自引用 CTE 速度很慢。使用临时表。stackoverflow.com/a/2741802/284240
我在表上确实有一个唯一的聚集索引。我把它交给数据库引擎优化顾问,它没有提出任何建议。您想要执行计划 xml 吗?
第一个 CTE 并没有真正的帮助。“时期”是什么意思?如果不理解“周期”,就很难完整地理解第二个 CTE。我个人的偏好:当我将表连接到自身时,我通常使用LandR作为别名(“左”和“右”)或在别名前面加上“L”和“R”,例如LsmaCBP和RsmaCBP。如果连接有一些特定的语义原因,那么我将使用它,例如ParentOrganismand ChildOrganism。
@HABO 谢谢。“期间”是描述移动平均值的天数,5、10、20 等。如果有帮助的话。
谢谢...很好,我修复了分区,就像我说的,我仍在制定逻辑。