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.

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top