SQL Cross Join sulla tabella Temp Slow Risultati
-
12-11-2019 - |
Domanda
Ho aggiunto il seguente codice alla mia query SQL: (Nota Taglia la versione)
DECLARE @rowType AS TABLE (
rowTypeLabel NVARCHAR (20));
INSERT INTO @rowType
VALUES ('Cumulative');
INSERT INTO @rowType
VALUES ('Non-Cumulative');
--select * from @rowType
SELECT ID,Name,StartDate,
EndDate,
rowTypeLabel AS Period
FROM dbo.sicky CROSS JOIN @rowType
WHERE (rowTypeLabel = 'Cumulative'
OR (rowTypeLabel = 'Non-Cumulative'
AND (EndDate IS NULL
OR EndDate BETWEEN CAST (DateAdd(Day, 1 - Day(getDate()), getdate()) AS DATE) AND CAST (DateAdd(month, 1, DateAdd(Day, -Day(getDate()), getdate())) AS DATE))));
Il tempo di esecuzione è passato da circa 10 minuti a circa 1 ora, qualcuno ha qualche suggerimento sul perché ciò possa essere, i risultati senza questo join incrociato sono stati di circa 46.000 e dopo aver restituito altre 231 file (tutto ciò che è classificato come "non -cumulative 'Secondo la query.
Soluzione
Immagino che questo sia un esempio molto semplificato? Quindi non posso darti i dettagli, ma la semplice risposta è che la parte cumulativa della query sta facendo molto più lavoro rispetto alla parte non cumulativa.
Prova questi due per il confronto ...
SELECT ID,Name,StartDate,
EndDate,
rowTypeLabel AS Period
FROM dbo.sicky
E...
SELECT ID,Name,StartDate,
EndDate,
rowTypeLabel AS Period
FROM dbo.sicky
WHERE EndDate IS NULL
OR EndDate BETWEEN CAST (DateAdd(Day, 1 - Day(getDate()), getdate()) AS DATE) AND CAST (DateAdd(month, 1, DateAdd(Day, -Day(getDate()), getdate())) AS DATE))));
Quest'ultimo, mi aspetterei, richiederà molto più tempo.
Anche, OR
Le condizioni per unire più pezzi di logica aziendale possono essere piuttosto difficili per l'ottimizzatore. Ciò significa che la seguente struttura Maggio Sii più efficiente ...
SELECT * FROM <non cumulative query>
UNION ALL
SELECT * FROM <cumulative query>
Altri suggerimenti
Non vedo perché hai bisogno del costrutto di un join incrociata qui - sta solo confondendo il problema. Riscriverei la domanda come questa:
SELECT ID, Name, StartDate, EndDate, 'Cumulative' AS Period
FROM dbo.sicky
UNION ALL
SELECT ID, Name, StartDate, EndDate, 'Non-Cumulative' AS Period
FROM dbo.sicky
WHERE EndDate IS NULL
OR EndDate BETWEEN CAST (DateAdd(Day, 1 - Day(getDate()), getdate()) AS DATE) AND CAST (DateAdd(month, 1, DateAdd(Day, -Day(getDate()), getdate())) AS DATE))));
Questo dovrebbe Sii equivalente, ma illustra ciò che stai facendo più chiaramente. Supponendo che la prima parte di questa unione sia ciò che avevi prima, e la seconda parte è ciò che è lento, è probabile che la data end (o qualunque cosa l'equivalente sia nella tua query reale) non sia indicizzato correttamente e sta causando una scansione eccessiva. Pubblica i tuoi piani di esecuzione per un'analisi più dettagliata.
46000 righe in 10 minuti per una semplice selezione senza join o sottoquerie ... sembra troppo. Controlla se sono stati creati e abilitati gli indici su StartDate e Enddate. Se è così, vado con le risposte Mwigdahl o Dems.