Domanda

Sto cercando di migliorare le prestazioni su una query che esegue molto lentamente. Dopo aver attraversato il piano di esecuzione effettivo ; Ho trovato che un Clustered Index Seek stava prendendo 82%. C'è un modo per me per migliorare le prestazioni su un Indice Seek ? Qui di seguito è un'immagine del problema Index Seek dal piano di esecuzione, così come l'indice e la tabella si sta usando.

alt http://img340.imageshack.us/img340/1346/seek testo. png

Indice:

/****** Object:  Index [IX_Stu]    Script Date: 12/28/2009 11:11:43 ******/
CREATE CLUSTERED INDEX [IX_Stu] ON [dbo].[stu] 
(
 [StuKey] ASC
)WITH (PAD_INDEX  = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]

Tabella (alcune colonne omesse per brevità):

CREATE TABLE [dbo].[stu](
 [StuCertKey] [int] IDENTITY(1,1) NOT NULL,
 [StuKey] [int] NULL
 CONSTRAINT [PK_Stu] PRIMARY KEY NONCLUSTERED 
(
 [StuCertKey] ASC
)WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
È stato utile?

Soluzione

sto generalizzando qui, ma ...

Un indice cluster cerchiamo è, per la maggior parte, la migliore delle ipotesi. Gli unici modi che posso pensare per migliorare le prestazioni sarebbero:

  • Aggiornare il query per restituire un minor numero di righe / colonne, se possibile;
  • Deframmentare o ricostruire l'indice;
  • Partizione l'indice su più dischi / server.

Se è solo il ritorno di 138 righe, ed è quel lento ... forse è stato bloccato da un altro processo? Stai provando questo in isolamento, o sono gli altri utenti / processi in linea allo stesso tempo? O forse è anche un problema hardware, come un guasto del disco.

Altri suggerimenti

indice cluster cerca verifica quando gli indici non cluster vengono utilizzati e non sono necessariamente un male.

Si consideri la seguente query:

SELECT s.StuKey, s.Name, s.Address, s.City, s.State FROM stu s WHERE State='TX'

Se c'è solo un indice cluster StuKey, quindi Sql Server ha solo 1 possibilità, dovrà eseguire la scansione dell'intera tabella alla ricerca di righe in cui Stato = "TX' e riprendere le righe.

Se si aggiunge un indice non cluster su Stato

CREATE INDEX IX_Stu_State on Stu (State)

Server Ora Sql ha una nuova opzione. Si può scegliere di cercare utilizzando l'indice non cluster, che produrrà le righe in cui Stato = 'TX'. Tuttavia, al fine di ottenere le restanti colonne di ritornare nella SELECT, si deve guardare in alto le colonne facendo un indice cluster cercano per ogni riga.

Se si vuole ridurre l'indice cluster cerca, allora si può fare il vostro indice di "copertura", includendo colonne aggiuntive in esso.

 CREATE INDEX IX_Stu_State2 on Stu (State) INCLUDE (name, address, city )

Questo indice contiene ora tutte le colonne necessarie per rispondere alla domanda di cui sopra. La query farà un indice cerca di restituire solo le righe in cui Stato = 'TX', e le colonne aggiuntive può essere tirato fuori dell'indice non cluster, quindi l'indice cluster cerca andare via.

Un indice cluster gamma chiedere che restituisce 138 righe non è il tuo problema.

Tecnicamente è possibile migliorare le prestazioni chiedere, rendendo l'indice cluster più stretto:

Entrambi possono avere un certo impatto drammatico sulla gamma tempo di ricerca, in quanto riducono l'IO e la necessità di colpire letture fisiche. Naturalmente, come al solito, il risultato può variare su un gran numero di altri fattori, come quello che fanno le colonne si proietta (sfrattare una colonna proiettato in unità di allocazione BLOB può effettivamente avere effetti negativi sulla determinate query). Come nota a margine, di solito la frammentazione avrà solo un impatto marginale su tale intervallo di scansione breve. Anche in questo caso, dipende.

Ma come ho detto, dubito fortemente questo è il vostro vero problema. Avete pubblicato solo le parti selezionate del piano ed i risultati della propria analisi. La vera causa principale può fissare completamente altrove.

Pensieri ...

  • Perché IX_Stu cluster? Internamente, SQL Server aggiunge un 4 byte "uniqueifier" per non univoci indici cluster. Qual è la giustificazione? Questo contribuisce ad appesantire anche il vostro PK troppo

  • Qual è la query effettiva si esegue?

  • Infine, perché FILLFACTOR 80%?

Modifica:

  • Un FILLFACTOR "normale" sarebbe del 90%, ma questa è una regola empirica solo

  • Un 11 join ricerca? Questo è più probabile che il vostro problema. Quali sono i join, le clausole WHERE ecc? Qual è il piano di testo completo?

Alcuni consigli generali: quando devo fare l'ottimizzazione delle query, ho iniziare a scrivere ciò che penso che il piano di esecuzione dovrebbe essere.

Una volta che ho deciso quello che penso il piano di esecuzione dovrebbe essere, provo a fare la query effettiva si adattano questo piano. Le tecniche per farlo sono diverse per ogni DBMS, e non necessariamente trasferiscono da uno all'altro, o anche, talvolta, tra le diverse versioni del DBMS.

La cosa da tenere a mente è che il DBMS non può che eseguire un join alla volta: si parte con due tavoli iniziali, si unisce a quelli, e poi prende il risultato di tale operazione e si unisce al tavolo accanto. L'obiettivo ad ogni passo è quello di minimizzare il numero di righe nel set di risultati intermedio (più correttamente, per ridurre al minimo il numero di blocchi che devono essere letti per produrre i risultati intermedi, ma questo significa generalmente minor numero di righe).

Hai provato un po 'di manutenzione su questo indice? Come deframmentare esso? Sembra davvero strano che costa più di tanto (120,381). Index Seek è l'operazione di indice più veloce, non dovrebbe prendere così a lungo. Puoi pubblicare la query?

Che cosa succede se si hard-code Dove i criteri, come questo:

SELECT StuCertKey, StuKey FROM stu 
WHERE stuKey in (/* list 50 values of StuKey here */)

Se è ancora molto lento, si dispone di un problema interno di qualche tipo. Se è più veloce, quindi l'indice non è il collo di bottiglia, è il JOIN che si sta facendo per creare la Dove del filtro.

Si noti che SELECT * può essere molto lento se ci sono molti grandi colonne, e soprattutto se ci sono i BLOB.

Controlla le statictics indice.

ricalcolare le statistiche cluster indice risolverà il problema.

nel mio caso, ero alla ricerca di 30 record in 40M recored. il piano di esecuzione dice che sta passando il-indice cluster, ma ci sono voluti circa 200ms. e l'indice non è stato deframmentato. dopo il ricalcolo IT di statistiche, è sempre fatto sotto 10ms!

Ricostruire l'indice, e calcolare le statistiche?

L'unico altro modo che mi viene in mente per accelerarlo di suddividere il tavolo, che può o non può essere possibile.

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