Prestazioni di indicizzazione null vs dati fittizi
-
06-07-2019 - |
Domanda
Ho una tabella con una colonna InTime e OutTime.
Normalmente quando inserisco i dati in questa tabella ho impostato InTime su DateTime e OutTime su null. Quando i dati vengono rimossi, viene impostato un valore OutTime.
Quando ricevo i dati per un determinato momento, utilizzo qualcosa del tipo:
where InTime < sometime and OutTime is > sometime or OutTime is null
La mia domanda è, in termini di miglioramento delle prestazioni di query / indice, dovrei mettere un valore in OutTime come il massimo datetime e rendere il campo non annullabile?
Quindi la mia query diventa
where InTime < sometime and OutTime is > sometime
Soluzione
Lascia il campo NULL. Non utilizzare OR, utilizzare UNION ALL:
select ... from ... where InTime < sometime and OutTime is > sometime
union all
select ... from ... where InTime < sometime and OutTime is null
L'uso di valori magici anziché NULL è una ricetta per il disastro. Almeno, utilizza più spazio di archiviazione. Più specificamente, interrompe la semantica di NULL quando si applicano i vincoli del database, quando si calcolano gli aggregati e nelle applicazioni.
L'uso di OR nelle query richiede problemi di prestazioni. L'ottimizzatore probabilmente trasformerà qualsiasi ricerca di intervallo di indici in scansioni. L'utilizzo di UNION è in genere migliore, poiché l'ottimizzatore creerà due piani, uno ottimale per i NULL, uno ottimale per i non NULL e li unisce.
Se non si dispone di alcun indice su Intime e / o OutTime, la query sarà comunque una scansione e l'UNION avrà prestazioni peggiori di un OR, ma non è uno scenario di cui valga la pena parlare. La domanda è, ovviamente, come ottimizzare una query su memoria progettata correttamente .