Modifica: +1 funziona in questa situazione perché si scopre che FILE_NUMBER
è una versione di stringa con riempimento zero di un numero intero. Una soluzione migliore qui per le stringhe è quella di aggiungere ''
(la stringa vuota), poiché l'aggiunta di un valore può influire sull'ordine o per i numeri di aggiungere qualcosa che è una costante ma contiene una funzione non deterministica, comesign(rand()+1)
. L'idea di "rompere l'ordinamento" è ancora valida qui, è solo che il mio metodo non era l'ideale.
+1
No, non intendo che sono d'accordo con nulla, intendo questo come soluzione. Se si modifica la query inORDER BY cj.FILE_NUMBER + 1
allora TOP 1
si comporterà diversamente.
Vedete, con l'obiettivo di una piccola riga in atto per una query ordinata, il sistema proverà a consumare i dati in ordine, per evitare di avere un operatore di ordinamento. Eviterà anche di costruire una tabella hash, immaginando che probabilmente non deve fare troppo lavoro per trovare quella prima riga. Nel tuo caso, questo è sbagliato - dallo spessore di quelle frecce, sembra che debba consumare molti dati per trovare una singola corrispondenza.
Lo spessore di quelle frecce suggerisce che la DOCUMENT_QUEUE
tabella (DQ) è molto più piccola della CORRESPONDENCE_JOURNAL
tabella (CJ). E che il piano migliore sarebbe effettivamente quello di controllare le righe DQ fino a quando non viene trovata una riga CJ. In effetti, questo è ciò che farebbe Query Optimizer (QO) se non avesse questo fastidioso problema ORDER BY
, che è ben supportato da un indice di copertura su CJ.
Quindi, se abbandoni ORDER BY
completamente, mi aspetto che otterrai un piano che includa un ciclo annidato, ripetendo le righe in DQ, cercando in CJ per assicurarsi che la riga esista. E con TOP 1
questo, questo si fermerebbe dopo che una singola fila era stata tirata.
Ma se in realtà hai bisogno della prima riga in FILE_NUMBER
ordine, allora potresti indurre il sistema a ignorare quell'indice che (in modo errato) sembra essere così utile, facendo ORDER BY CJ.FILE_NUMBER+1
- che sappiamo manterrà lo stesso ordine di prima, ma soprattutto il QO non lo fa. Il QO si concentrerà sulla realizzazione dell'intero set, in modo tale che un operatore Top N Sort possa essere soddisfatto. Questo metodo dovrebbe produrre un piano che contenga un operatore di calcolo scalare per calcolare il valore per l'ordinamento e un operatore di ordinamento Top N per ottenere la prima riga. Ma a destra di questi, dovresti vedere un bel Nested Loop, facendo un sacco di ricerche su CJ. E prestazioni migliori rispetto a una grande tabella di righe che non corrisponde a nulla in DQ.
L'Hash Match non è necessariamente terribile, ma se l'insieme di righe che stai tornando da DQ è molto più piccolo di CJ (come mi aspetterei che fosse), allora Hash Match scansionerà molto più CJ del necessario.
Nota: ho usato +1 anziché +0 perché è probabile che Query Optimizer riconosca che +0 non cambi nulla. Certo, la stessa cosa potrebbe valere per il +1, se non ora, poi ad un certo punto in futuro.
DOCUMENT_ID
relazione tra le due tabelle (o ogni record inCORRESPONDENCE_JOURNAL
ha un record corrispondente inDOCUMENT_QUEUE
)?