È necessario eseguire una ricerca per tutte le condizioni e per ogni join ... a condizione. I due funzionano allo stesso modo.
Supponiamo di scrivere
select name
from customer
where customerid=37;
In qualche modo il DBMS deve trovare il record o il record con CustomerID = 37. Se non c'è un indice, l'unico modo per farlo è leggere ogni record nella tabella confrontando il customerid a 37. Anche quando ne trova uno, non ha modo di sapere che ce n'è uno solo, quindi deve continuare a cercare altri.
Se si crea un indice su customerid, il DBMS ha modi per cercare l'indice molto rapidamente. Non è una ricerca sequenziale, ma, a seconda del database, una ricerca binaria o qualche altro metodo efficiente. Esattamente come non importa, accetta che sia molto più veloce del sequenziale. L'indice quindi lo porta direttamente al record o ai record appropriati. Inoltre, se si specifica che l'indice è "univoco", il database sa che ce ne può essere solo uno in modo da non perdere tempo a cercare un secondo. (E il DBMS ti impedirà l'aggiunta di un secondo.)
Ora consideriamo questa query:
select name
from customer
where city='Albany' and state='NY';
ora abbiamo due condizioni. Se si dispone di un indice su uno solo di questi campi, il DBMS utilizzerà tale indice per trovare un sottoinsieme dei record, quindi li ricerca in sequenza.Ad esempio, se si dispone di un indice su stato, il DBMS troverà rapidamente il primo record per NY, quindi cerca in sequenza cercando city = 'Albany' e smette di cercare quando raggiunge l'ultimo record per NY.
Se si dispone di un indice che include entrambi i campi, ad esempio "creare indice su cliente (stato, città)", il DBMS può immediatamente eseguire lo zoom sui record corretti.
Se si dispone di due indici separati, uno su ciascun campo, il DBMS avrà varie regole a cui si applica per decidere quale indice utilizzare. Di nuovo, esattamente come questo viene fatto dipende dal particolare DBMS che si sta usando, ma fondamentalmente cerca di mantenere le statistiche sul numero totale di record, il numero di valori diversi e la distribuzione dei valori. Quindi cercherà sequenzialmente quei record per quelli che soddisfano l'altra condizione. In questo caso il DBMS probabilmente osserverebbe che ci sono molte più città di quante siano gli stati, quindi usando l'indice della città può rapidamente ingrandire i record di 'Albany'. Quindi cercherà sequenzialmente questi, controllando lo stato di ciascuno contro "NY". Se si dispone di record per Albany, California, questi verranno saltati.
Ogni join richiede una sorta di ricerca.
dire che scriviamo
select customer.name
from transaction
join customer on transaction.customerid=customer.customerid
where transaction.transactiondate='2010-07-04' and customer.type='Q';
Ora il DBMS deve decidere quale tabella da leggere prima, selezionare i record appropriati da lì, e poi trovare i record corrispondenti in altra tabella.
Se si dispone di un indice su transaction.transactiondate e customer.customerid, il piano migliore sarebbe probabilmente trovare tutte le transazioni con questa data, quindi per ciascuna di esse trovare il cliente con il customerid corrispondente, quindi verificare che il cliente ha il tipo giusto
Se non si dispone di un indice su customer.customerid, il DBMS potrebbe trovare rapidamente la transazione, ma poi per ogni transazione dovrebbe cercare in sequenza la tabella clienti cercando un customerid corrispondente. (Questo potrebbe essere molto lento.)
Supponiamo invece che gli unici indici presenti siano su transaction.customerid e customer.type. Quindi il DBMS probabilmente userebbe un piano completamente diverso. Probabilmente eseguirà la scansione della tabella clienti per tutti i clienti con il tipo corretto, quindi ognuno di questi trova tutte le transazioni per questo cliente e li ricerca in sequenza per la data corretta.
La chiave più importante per l'ottimizzazione è capire quali indici saranno veramente utili e creare quegli indici. Gli indici extra non utilizzati sono un onere per il database perché richiede lavoro per mantenerli, e se non vengono mai utilizzati questo è uno sforzo inutile.
È possibile indicare quali indici il DBMS utilizzerà per qualsiasi query specificata con il comando EXPLAIN. Lo uso sempre per determinare se le mie query sono ottimizzate bene o se dovrei creare indici aggiuntivi. (Leggi la documentazione su questo comando per una spiegazione del suo output.)
Avvertenza: Ricordare che il DBMS mantiene statistiche sul numero di record e sul numero di valori diversi e così via in ciascuna tabella. EXPLAIN potrebbe darti un piano completamente diverso rispetto a ieri se i dati sono cambiati. Ad esempio, se si dispone di una query che unisce due tabelle e una di queste tabelle è molto piccola mentre l'altra è grande, verrà polarizzata prima di leggere la tabella piccola e quindi trovare i record corrispondenti nella tabella grande. L'aggiunta di record a una tabella può cambiare che è più grande e quindi portare il DBMS a modificare il suo piano. Pertanto, dovresti provare a ESPLORARE contro un database con dati realistici. L'esecuzione su un database di test con 5 record in ogni tabella ha un valore molto inferiore rispetto all'esecuzione su un database attivo.
Bene, c'è molto altro che si può dire, ma non voglio scrivere un libro qui.
Wow, sono molte informazioni, grazie, ho imparato un paio di cose leggendo questo che posso usare immediatamente – walnutmon