Domanda

In Oracle, quando si richiede l'esistenza di una riga, perché Seleziona 1 è più veloce di Seleziona conteggio (*)?

È stato utile?

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.

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).

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