7 sql-server-2008 sql-server sql-server-2008-r2
我终于找到了查询的逻辑,现在我需要加快速度......如果可能的话(它运行 40 分钟 +/-)。它位于两张桌子上,一张只有几百行 ( tblTradingDays),另一张有超过一百万行 ( tblDailySMA)。它返回 4800 万行。
我的基本逻辑是:我为交易品种、交易日期和周期值的每个组合返回一行,创建一个“慢v 快”周期对。所以在原始表中,有一个符号、一个交易日期、一个周期 (5,10,20,...) 和该组合的实际值。我想比较所有期间组合的值(期间 p1 = 期间 p2 除外)。我正在对要用于进一步处理的记录进行编号。希望这是有道理的。
我尝试了连接和谓词中涉及的字段的各种索引和组合。在估计的执行计划中,看起来排序是最昂贵的操作。tblDailySMA尽管我添加了其他索引,但该计划中出现的唯一索引是非聚集的、唯一的、 on:Symbol, TradeDate, Period和 includes Value。它被扫描。查询如下,希望有人可以帮助我。提前致谢..
SELECT
ROW_NUMBER() OVER
(
ORDER BY t1.Symbol, t1.Period, t2.Period, t.TradingDate DESC
) RowNum,
t1.Symbol, t.TradingDate, t1.Period, t2.Period, t1.Value FastValue,
t2.Value SlowValue, (t1.Value - t2.Value) SlowFastDiff,
ChgSign = CASE WHEN t1.Value < t2.Value THEN 0
WHEN t1.Value >= t2.Value THEN 1
WHEN t1.Value IS NULL OR t2.Value IS NULL THEN NULL
END
FROM
tblTradingDays t
RIGHT JOIN
tblDailySMA t1 ON t.TradingDate = t1.TradeDate
INNER JOIN
tblDailySMA t2 ON t1.Symbol = t2.Symbol AND t1.TradeDate = t2.TradeDate
WHERE
t1.Period < t2.Period
Run Code Online (Sandbox Code Playgroud)
这是执行计划:
|--Compute Scalar(DEFINE:([Expr1007]=[Market].[dbo].[tblDailySMA].[Value] as [t1].[Value]-[Market].[dbo].[tblDailySMA].[Value] as [t2].[Value], [Expr1008]=CASE WHEN [Market].[dbo].[tblDailySMA].[Value] as [t1].[Value]<[Market].[dbo].[tblDailySMA].[Value] as [t2].[Value] THEN (0) ELSE CASE WHEN [Market].[dbo].[tblDailySMA].[Value] as [t1].[Value]>=[Market].[dbo].[tblDailySMA].[Value] as [t2].[Value] THEN (1) ELSE NULL END END))
|--Sequence Project(DEFINE:([Expr1006]=row_number))
|--Segment
|--Parallelism(Gather Streams, ORDER BY:([t1].[Symbol] ASC, [t1].[Period] ASC, [t2].[Period] ASC, [t].[TradingDate] DESC))
|--Sort(ORDER BY:([t1].[Symbol] ASC, [t1].[Period] ASC, [t2].[Period] ASC, [t].[TradingDate] DESC))
|--Hash Match(Right Outer Join, HASH:([t].[TradingDate])=([t1].[TradeDate]), RESIDUAL:([Market].[dbo].[tblTradingDays].[TradingDate] as [t].[TradingDate]=[Market].[dbo].[tblDailySMA].[TradeDate] as [t1].[TradeDate]))
|--Parallelism(Distribute Streams, Hash Partitioning, PARTITION COLUMNS:([t].[TradingDate]))
| |--Index Scan(OBJECT:([Market].[dbo].[tblTradingDays].[PK_tblTradingDays] AS [t]))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([t1].[TradeDate]))
|--Merge Join(Inner Join, MANY-TO-MANY MERGE:([t1].[Symbol], [t1].[TradeDate])=([t2].[Symbol], [t2].[TradeDate]), RESIDUAL:([Market].[dbo].[tblDailySMA].[Symbol] as [t1].[Symbol]=[Market].[dbo].[tblDailySMA].[Symbol] as [t2].[Symbol] AND [Market].[dbo].[tblDailySMA].[TradeDate] as [t1].[TradeDate]=[Market].[dbo].[tblDailySMA].[TradeDate] as [t2].[TradeDate] AND [Market].[dbo].[tblDailySMA].[Period] as [t1].[Period]<[Market].[dbo].[tblDailySMA].[Period] as [t2].[Period]))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([t1].[Symbol], [t1].[TradeDate]), ORDER BY:([t1].[Symbol] ASC, [t1].[TradeDate] ASC))
| |--Index Scan(OBJECT:([Market].[dbo].[tblDailySMA].[IX_tblDailySMA_Noncl_SymbTrDatePer] AS [t1]), ORDERED FORWARD)
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([t2].[Symbol], [t2].[TradeDate]), ORDER BY:([t2].[Symbol] ASC, [t2].[TradeDate] ASC))
|--Index Scan(OBJECT:([Market].[dbo].[tblDailySMA].[IX_tblDailySMA_Noncl_SymbTrDatePer] AS [t2]), ORDERED FORWARD)
Run Code Online (Sandbox Code Playgroud)
小智 3
当我在大型查询中遇到此类性能问题时,我将其拆分为带有临时表的小型查询。对我来说这是一个解决方案,性能比可能是 10 比 1 或更高。
第一步:
with t1 as (
SELECT
t1.Symbol,
t1.Period,
t.TradingDate,
t1.Value as FastValue
FROM tblDailySMA t1
LEFT JOIN tblTradingDays t
ON t.TradingDate = t1.TradeDate
)
select *
into #t1
from t1;
--I include period into idex to avoid table access on next query
create index t1_idx on ( Symbol, TradeDate, Period )
Run Code Online (Sandbox Code Playgroud)
第二步:
with t2 as (
SELECT
t1.Symbol,
t1.Period as period_t1,
t.TradingDate,
t1.Value as FastValue
t2.Period as period_t2,
t2.Value as SlowValue,
t2.TradeDate
FROM #t1 as t1
INNER JOIN tblDailySMA t2
ON t1.Symbol = t2.Symbol AND t1.TradeDate = t2.TradeDate
WHERE t1.Period < t2.Period
)
select
*
into #t2
from t2;
--Here create indexes for t2
--Here next and final query
Run Code Online (Sandbox Code Playgroud)
等等。该系统的好处之一是您可以逐步改进查询。
| 归档时间: |
|
| 查看次数: |
576 次 |
| 最近记录: |