Ich habe endlich die Logik für eine Abfrage herausgefunden, jetzt muss ich sie beschleunigen ... dramatisch, wenn möglich (sie läuft 40 Minuten +/-). Es steht auf zwei Tischen, einer mit nur ein paar hundert Zeilen ( tblTradingDays
) und der andere mit über einer Million ( tblDailySMA
). Es werden 48 Millionen Zeilen zurückgegeben.
Meine grundlegende Logik lautet: Ich gebe für jede Kombination aus Symbol-, Handelsdatum- und Periodenwerten eine Zeile zurück und erstelle ein "langsames v schnelles" Periodenpaar. In der Originaltabelle gibt es also ein Symbol, ein Handelsdatum, einen Zeitraum (5,10,20, ...) und den tatsächlichen Wert für diese Kombination. Ich möchte die Werte für alle Kombinationen von Perioden vergleichen (außer Periode p1 = Periode p2). Ich nummeriere die Datensätze, die für die weitere Verarbeitung verwendet werden sollen. Hoffe das macht Sinn.
Ich habe verschiedene Indizes und Kombinationen der Felder ausprobiert, die an den Verknüpfungen und Prädikaten beteiligt sind. Im geschätzten Ausführungsplan sieht es so aus, als wäre eine Sortierung die teuerste Operation. Der einzige Index tblDailySMA
, der im Plan angezeigt wird, obwohl ich andere hinzufüge, ist nicht gruppiert, eindeutig, auf: Symbol, TradeDate, Period
und enthält Value
. Es wird gescannt. Die Frage ist unten, hoffentlich kann mir jemand helfen. Danke im Voraus..
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
Hier ist der Ausführungsplan:
|--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)
tblTradingDays
? Sieht so aus, als würde es nichts tun. Oder möchten Sie vielleichtLEFT JOIN
stattdessenRIGHT JOIN
?Antworten:
Wenn ich diese Art von Leistungsproblemen in einer großen Abfrage habe, teile ich sie in kleine Abfragen mit temporären Tabellen auf. Für mich ist es eine Lösung und das Leistungsverhältnis kann 10 zu 1 oder mehr betragen.
Erster Schritt:
Zweiter Schritt:
Und so weiter. Ein Vorteil dieses Systems besteht darin, dass Sie Abfragen Schritt für Schritt verbessern können.
quelle