2012-07-11 10 views
75

Diciamo che ho una tabella denominata PEOPLE con 3 colonne ID, LastName, FirstName, nessuna di queste colonne è indicizzata.
LastName è più esclusivo e FirstName è meno esclusivo.L'ordine in cui le clausole sono importanti in SQL

Se faccio 2 ricerche:

select * from PEOPLE where FirstName="F" and LastName="L" 
select * from PEOPLE where LastName="L" and FirstName="F" 

La mia convinzione è la seconda è più veloce perché il criterio più unico (LastName) viene prima nella clausola where, e le registrazioni otterrà eliminato in modo più efficiente. Non penso che l'ottimizzatore sia abbastanza intelligente da ottimizzare il primo sql.

La mia comprensione è corretta?

+7

No, questo ordine non ha importanza - qualsiasi ottimizzatore di query decente esaminerà ** tutte ** le clausole WHERE e individuerà il modo più efficiente per soddisfare tale query –

+3

Quali sono state le tue osservazioni quando hai eseguito queste due dichiarazioni? Come sono stati i piani di esecuzione? –

+3

Ti riferisci a un RDBMS specifico? Ci sono davvero differenze. – Bjoern

risposta

64

No, questo ordine non ha importanza (o almeno: non dovrebbe importare).

Qualsiasi Query Optimizer decente esaminerà tutte le parti della clausola WHERE e capire il modo più efficiente per soddisfare tale richiesta.

So che SQL Server Query Optimizer sceglierà un indice adatto, indipendentemente dall'ordine in cui si trovano le due condizioni. Suppongo che altri RDBMS abbiano strategie simili.

Ciò che importa è se non si dispone di un indice adatto per questo!

Nel caso di SQL Server, è probabile che utilizzare un indice, se si dispone di:

  • un indice su (LastName, FirstName)
  • un indice su (FirstName, LastName)
  • un indice solo su (LastName), o semplicemente (FirstName) (o entrambi)

D'altra parte - ancora una volta per SQL Server - se si utilizza SELECT * per afferrare tutte le colonne da una tabella e la tabella è piuttosto piccola, quindi ci sono buone probabilità che Query Optimizer esegua solo una scansione della tabella (o dell'indice cluster) invece di utilizzare un indice (perché la ricerca nella pagina di dati completa per ottenere tutte le altre colonne diventano troppo costose molto rapidamente).

+0

Se non c'è alcun indice (es) op potrebbe essere giusto, a seconda dei dati. Certo che fare qualcosa del genere senza indici, sarebbe una strana decisione ... –

+0

@TonyHopkinson: Non credo - anche senza indici dubito che ci sia alcuna differenza. Dopotutto: senza indici, che altro può fare una scansione completa della tabella, RDBMS, davvero ?? –

+2

Interessante nota a margine con SQL server, apparentemente l'ordine di NON ESISTE nei predicati può effettivamente influenzare la creazione del piano: http://bradsruminations.blogspot.com/2010/04/looking-under-hood.html –

2

No, tutti gli RDBM iniziano innanzitutto analizzando la query e ottimizzandola riordinando la clausola where.

A seconda di quale RDBM siete voi utilizzando in grado di visualizzare ciò che è il risultato della analisi (ricerca di spiegare piano in Oracle per esempio)

M.

+0

Lo fa in base agli indici. Quindi è indiretto in termini di contenuto. –

+0

infatti questo viene fatto principalmente sulla base delle statistiche della tabella – poussma

9

L'ordine delle clausole WHERE non dovrebbero fare un differenza in un database conforme allo standard SQL. L'ordine di valutazione non è garantito nella maggior parte dei database.

Non pensare che SQL si preoccupi per l'ordine.Di seguito genera un errore in SQL Server:

select * 
from INFORMATION_SCHEMA.TABLES 
where ISNUMERIC(table_name) = 1 and CAST(table_name as int) <> 0 

Se la prima parte di questa clausola è stato eseguito per primo, i nomi di tabella allora solo numerici saranno espressi come numeri interi. Tuttavia, non riesce, fornendo un chiaro esempio che SQL Server (come con altri database) non si preoccupa dell'ordine delle clausole nell'istruzione WHERE.

+0

Che cosa ha a che fare la query che causa un errore con l'ordine della valutazione dei predicati WHERE? – Jim

+3

@Jim Se "ISNUMERIC (nome_tabella) = 1" è stato valutato per primo, quindi "CAST" viene chiamato solo per i nomi di tabelle numeriche. Ma poiché non viene valutato per primo, 'CAST' viene valutato anche per nomi di tabelle non numeriche, causando il messaggio di errore. – hibbelig

+0

Chiarimento eccellente – neeohw

0

È vero fino in fondo, supponendo che i nomi non siano indicizzati. Tuttavia, dati diversi potrebbero essere sbagliati. Per scoprire in che modo farlo, che potrebbe essere diverso ogni volta, il DBMS dovrebbe eseguire una query di conteggio distinta per ogni colonna e confrontare i numeri, che costerebbe più di una semplice scrollata di spalle e di andare avanti con essa.

6

ANSI SQL Draft 2003 5WD-01-quadro-2003-09.pdf

6.3.3.3 ordine di valutazione Regola

...

Dove la precedenza non è determinato dai formati o per parentesi, la valutazione effettiva delle espressioni viene generalmente eseguita da sinistra a destra. Tuttavia, dipende dall'implementazione se le espressioni vengono effettivamente valutate da sinistra a destra, in particolare quando gli operandi o gli operatori possono causare l'aumento delle condizioni o se i risultati delle espressioni possono essere determinati senza valutare completamente tutte le parti dell'espressione.

copiati da here

1

dichiarazione OP originale

La mia convinzione è la seconda è più veloce perché il criterio più unico (Cognome) viene prima in> clausola where, e le registrazioni otterrà eliminato più in modo efficiente. Non penso che l'ottimizzatore sia> abbastanza intelligente da ottimizzare il primo sql.

immagino che stai confondendo questo con la selezione l'ordine delle colonne durante la creazione degli indici in cui devi mettere le colonne più selettivi prima di secondo più selettivo e così via.

BTW, per le due query precedenti SQL Server Optimizer non eseguirà alcuna ottimizzazione, ma utilizzerà il piano Trivila purché il costo totale del piano sia inferiore al costo della soglia di parallelismo.

Problemi correlati