2008-10-24 30 views
17

Sono stato incaricato di ottimizzare alcune query SQL al lavoro. Tutto ciò che ho trovato punta all'utilizzo di Explain Plan per identificare le aree problematiche. Il problema non riesco a scoprire esattamente cosa spieghi il piano mi sta dicendo. Ottieni costo, cardinalità e byte.Come utilizzare Explain Plan per ottimizzare le query?

Cosa indicano e come dovrei utilizzarlo come guida. I numeri bassi sono migliori? Molto meglio? Qualsiasi input sarebbe molto apprezzato.

Oppure, se si dispone di un modo migliore per ottimizzare l'interrogazione, sarei interessato.

risposta

8

Si ottiene più di questo in realtà a seconda di ciò che si sta facendo. Dai un'occhiata a questa pagina explain plan. Sto assumendo un po 'qui che stai usando Oracle e so come eseguire lo script per visualizzare l'output del piano. Quello che potrebbe essere più importante iniziare è guardare il lato sinistro per l'uso di un particolare indice o meno e come viene utilizzato quell'indice. Dovresti vedere cose come "(Full)", "(By Index Rowid)", ecc. Se stai facendo join. Il costo sarebbe la prossima cosa da considerare con costi inferiori, e noterai che se stai facendo un join che non sta usando un indice potresti avere un costo molto alto. Si consiglia inoltre di leggere i dettagli su explain plan columns.

+0

Apprezzo l'aiuto, e in particolare i collegamenti. Sta iniziando a farmi da ora. Grazie ancora per l'aiuto. –

+1

I join che non usano gli indici potrebbero essere brutti, potrebbero essere i migliori.Tutto dipende. non, non farlo, non cercare di eliminare ogni scansione completa della tabella con gli indici. –

6

Hai la parte sfocata del lecca-lecca.

Non c'è assolutamente alcun modo, in isolamento, senza una tonnellata di informazioni aggiuntive e di esperienza, di guardare un piano di spiegare e determinare quali (se non altro) sta causando meno di prestazioni ottimali. Se la sintonizzazione delle query potrebbe essere ridotta a un processo di 10 passaggi, sarebbe eseguita da un processo automatizzato. Stavo per elencare tutte le cose che devi capire per essere efficaci, ma sarebbe una lista molto lunga.

l'unica risposta breve che riesco a pensare ... è la ricerca di passaggi nel piano che stanno attraversando molti più byte di quanto si possa immaginare. Quindi pensa a come puoi ridurre quel numero ... tramite un indice o partizionamento.

Scherzi a parte, ottenere il libro di Jonathan Lewis sulla base dei costi di Oracle Fundementals

Prendi il libro di Tom Kyte su Oracle database di Architettura e affittare una cabina nei boschi per un paio di settimane.

+0

Avevo iniziato a pensare che non fosse così semplice come mi era stato originariamente descritto al lavoro. Grazie per i suggerimenti del libro, saranno aggiunti alla mia lista di libri da leggere. –

+1

Non aggiungerli semplicemente alla coda ... spostali verso l'alto e fai tutto il possibile per leggerli. Direi prima il libro di Lewis. Dipende interamente dal significato di un piano di spiegazione, anche se non è scritto in questo modo. –

4

Questa è una vasta area di competenza (ovvero un'arte nera).

L'approccio che generalmente prendo è:

  1. esegue l'istruzione SQL in questione,
  2. ottenere il piano vero e proprio (guardare in alto DBMS_XPLAN),
  3. Confrontare il numero stimato di righe (cardinalità) vs numero effettivo di righe. Una grande differenza indica un problema da risolvere (ad es. Indice, istogramma)
  4. Considerare se è possibile creare un indice per accelerare una parte del processo (generalmente laddove si ritiene concettualmente che il piano debba iniziare per primo). Prova alcuni indici.

è necessario capire la O() impatto dei diversi indici nel contesto di ciò che si sta chiedendo il database. Ti aiuta a capire strutture di dati come alberi b, tabelle hash, ecc. Quindi, crea un indice che funzioni e ripeti il ​​processo.

Se Oracle decide di non utilizzare l'indice, applica un suggerimento INDICE() e guarda il nuovo piano. Il costo sarà maggiore del piano che ha scelto: è per questo che non ha scelto il tuo indice.Il piano suggerito potrebbe portare ad alcune informazioni sul perché il tuo indice non è buono.

+0

Oracle non ha scelto di usare un indice mi è sembrato strano all'inizio, fino alla tua spiegazione sopra, e ora mi rendo conto di essere più profondo di quanto non avessi mai capito. Se solo avessero un DBA con esperienza per lavorare con noi, staremmo meglio. –

7

Suppongo anche che stiate usando Oracle. E ti consiglio anche di dare un'occhiata alla pagina web del piano di spiegazioni, per i principianti. C'è molto da ottimizzare, ma può essere imparato.

Alcuni consigli seguono:

In primo luogo, quando le attività qualcuno di ottimizzare, sono quasi sempre alla ricerca di prestazioni accettabili, piuttosto che l'ultima prestazione. Se è possibile ridurre il tempo di esecuzione di una query da 3 minuti a 3 secondi, non sudare riducendolo a 2 secondi, fino a quando non viene richiesto.

In secondo luogo, fare un rapido controllo per assicurarsi che le query si sta ottimizzando sono logicamente corrette. Sembra assurdo, ma non posso dirti quante volte mi è stato chiesto un consiglio su una query a esecuzione lenta, solo per scoprire che occasionalmente forniva risposte sbagliate! E come risulta, il debug della query spesso si è rivelato anche per velocizzarlo.

In particolare, cercare la frase "Cartesian Join" nel piano di spiegazioni. Se lo vedi lì, è molto probabile che tu abbia trovato un join cartesiano involontario. Il solito schema per un join cartesiano non intenzionale è che la clausola FROM elenca le tabelle separate da virgola e le condizioni di join sono nella clausola WHERE. Tranne che manca una delle condizioni di join, in modo che Oracle non abbia altra scelta che eseguire un join cartesiano. Con tavoli di grandi dimensioni, questo è un disastro di prestazioni.

E 'possibile vedere un join cartesiano nel piano di spiegare dove la query è logicamente corretto, ma mi associano questo con le versioni precedenti di Oracle.

Cerca anche l'indice composto inutilizzato. Se la prima colonna di un indice composto non viene utilizzata nella query, Oracle potrebbe utilizzare l'indice in modo inefficiente o non farlo affatto. Vi faccio un esempio:

La query è stata:

select * from customers  
where 
    State = @State 
    and ZipCode = @ZipCode 

(Il DBMS Oracle non era, quindi la sintassi era diverso, e ho dimenticato la sintassi originale).

Un rapido sguardo agli indici ha rivelato un indice su Clienti con le colonne (Paese, Stato, Codice postale) in questo ordine. Ho cambiato la query per leggere

select * from customers 
    where Country = @Country 
     and State = @State 
     and ZipCode = @ZipCode 

e ora è imbattuto in circa 6 secondi invece di circa 6 minuti, perché l'ottimizzatore era in grado di utilizzare l'indice per buon vantaggio. Ho chiesto ai programmatori di applicazioni perché avevano omesso il paese dai criteri, e questa è stata la loro risposta: sapevano che tutti gli indirizzi avevano paese uguale a 'USA' così hanno capito che potevano accelerare la query lasciando tale criterio fuori!

Purtroppo, ottimizzando il recupero del database non è davvero lo stesso di microsecondi rasatura fuori di tempo di calcolo. Comprende la comprensione della progettazione del database, in particolare degli indici, e almeno una panoramica di come l'ottimizzatore svolge il proprio lavoro.

in genere si ottiene risultati migliori dal ottimizzatore quando si impara a collaborare con esso, invece di cercare di superare in astuzia esso.

Buona fortuna per l'ottimizzazione!

+0

Grazie per il consiglio. Mi sono anche imbattuto nel problema di Join Cartesiano che hai menzionato sopra in alcune altre domande a cui stava lavorando e che ha fatto un'enorme differenza nel tempo e ora le query restituiscono effettivamente quello che dovrebbero. Vai a capire. –

Problemi correlati