Perché Select 1 è più veloce di Select count (*)?
-
05-07-2019 - |
Domanda
In Oracle, quando si richiede l'esistenza di una riga, perché Seleziona 1 è più veloce di Seleziona conteggio (*)?
Soluzione
Poiché Oracle non supporta IF EXISTS in PL / SQL, il suggerimento di CodeByMidnight di utilizzare EXISTS verrebbe normalmente eseguito con qualcosa del genere
SELECT 1
INTO l_local_variable
FROM dual
WHERE EXISTS(
SELECT 1
FROM some_table
WHERE some_column = some_condition );
Oracle sa che può interrompere l'elaborazione della clausola WHERE EXISTS non appena viene trovata una riga, quindi non deve potenzialmente contare un gran numero di righe che soddisfano i criteri. Questo è meno preoccupante, ovviamente, se stai verificando se esiste una riga con una chiave particolare rispetto a se stai controllando una condizione che coinvolge colonne non indicizzate o una condizione che potrebbe comportare la restituzione di un numero elevato di righe.
(Nota: vorrei poterlo pubblicare come commento sul post di CodeByMidnight, ma i commenti non possono includere il codice formattato).
AGGIORNAMENTO: dato il chiarimento che il poster originale ha fatto nel loro commento, la risposta breve e definitiva è che un SELECT 1
o SELECT COUNT (1)
non è più veloce di un SELEZIONA COUNT (*)
. Contrariamente alle linee guida di codifica che stai osservando, COUNT (*)
è il modo preferito di contare tutte le righe. C'era un vecchio mito secondo cui un COUNT (1)
era più veloce. Come minimo, ciò non è stato vero in nessuna versione di Oracle rilasciata negli ultimi dieci anni ed è improbabile che sia mai stato vero. Era comunque una convinzione diffusa. Oggi, il codice che fa un COUNT (1)
piuttosto che un COUNT (*)
generalmente mi fa sospettare che l'autore sia incline a credere a vari miti di Oracle, motivo per cui vorrei suggerisce di utilizzare COUNT (*)
.
Altri suggerimenti
È ancora meglio usare EXISTS dove RDBMS lo supporta o un equivalente, poiché questo interromperà l'elaborazione delle righe non appena troverà una corrispondenza.
Sarei sorpreso se il conteggio delle selezioni (*) non fosse ottimizzato correttamente, non è necessario caricare tutte le colonne poiché non ci sarà alcuna elaborazione relativa alle colonne.
http://www.dbasupport.com/forums /archive/index.php/t-28741.html
Almeno per Oracle.
Poiché una stella prende tutti i punti nel conteggio, "1" è un tipo di dati nativo.
In MySQL " SELECT COUNT (name_of_the_primary_key) " dovrebbe essere veloce come il tuo SELECT 1. È l'indice che conta. Un conteggio () su un indice dovrebbe essere abbastanza veloce;)
Non credo sia vero per Oracle. http://justoracle.blogspot.com/2006/12/count- vs-count1.html
Ma in alcuni database il motivo è che '*' deve visitare i metadati delle tabelle. Questo tende ad aggiungere un sovraccarico non necessario. Dove as 1 è solo un letterale.
A parità di altre condizioni, " seleziona 1 da my_table "
restituirà il primo risultato più veloce di " seleziona il conteggio (*) da my_table "
, ma se si recuperano tutti i risultati dalla query, il count (*)
sarà più veloce perché coinvolge molti meno dati (1 intero, anziché 1 intero per ogni riga nella tabella).