it-swarm.it

Dovrei usare molti indici a campo singolo, anziché specifici indici multi colonna?

Questa domanda riguarda l'efficacia di una tecnica di indicizzazione di SQL Server. Penso che sia noto come "intersezione dell'indice".

Sto lavorando con un'applicazione esistente di SQL Server (2008) che presenta numerosi problemi di prestazioni e stabilità. Gli sviluppatori hanno fatto alcune cose strane con l'indicizzazione. Non sono stato in grado di ottenere parametri di riferimento conclusivi su questi problemi, né posso trovare alcuna documentazione davvero valida su Internet.

Esistono molte colonne ricercabili su una tabella. Gli sviluppatori hanno creato un indice a colonna singola su OGNI colonna ricercabile. La teoria era che SQL Server sarebbe stato in grado di combinare (intersecare) ciascuno di questi indici per accedere in modo efficiente alla tabella in circostanze la maggior parte. Ecco un esempio semplificato (la tabella reale ha più campi):

CREATE TABLE [dbo].[FatTable](
    [id] [bigint] IDENTITY(1,1) NOT NULL,
    [col1] [nchar](12) NOT NULL,
    [col2] [int] NOT NULL,
    [col3] [varchar](2000) NOT NULL, ...

CREATE NONCLUSTERED INDEX [IndexCol1] ON [dbo].[FatTable]  ( [col1] ASC )
CREATE NONCLUSTERED INDEX [IndexCol2] ON [dbo].[FatTable] ( [col2] ASC )

select * from fattable where col1 = '2004IN' 
select * from fattable where col1 = '2004IN' and col2 = 4

Penso che gli indici a più colonne mirati ai criteri di ricerca siano molto migliori, ma potrei sbagliarmi. Ho visto piani di query che mostrano che SQL Server esegue una corrispondenza hash su due ricerche di indice. Forse questo ha senso quando non sai come viene cercata la tabella? Grazie.

36
RaoulRubin

Ciò di cui hai bisogno sono che coprono indici, ad es. indici che possono soddisfare una query da soli. Ma un indice "di copertura" presenta un problema: copre una query specifica . Quindi, al fine di sviluppare una buona strategia di indicizzazione, è necessario comprendere il carico di lavoro: quali query stanno colpendo il database, quali sono critiche e quali no, con quale frequenza viene eseguito ogni tipo di query, ecc. ecc. ecc. E poi si compensa questo con il costo di scrittura e aggiornamento di ciascun indice, e lì si ha la propria strategia di indicizzazione. Se sembra complicato è perché è complicato.

Tuttavia è possibile applicare alcune regole pratiche. Il MSDN copre abbastanza bene le basi:

C'è anche una miriade di articoli forniti dalla community, ad es. Registrazione Webcast - DBA Darwin Awards: Index Edition .

E per rispondere in modo specifico alla tua domanda: indici separati su ogni colonna possono funzionare, a condizione che ogni colonna abbia un'alta selettività (molti valori distinti, ogni valore appare solo poche volte nel database). Il piano di accesso risultante che utilizza un hash join tra due scansioni dell'intervallo di indice di solito funziona abbastanza bene. Le colonne con bassa selettività (pochi valori distinti, ogni valore che appare più volte nel database) non ha senso essere indicizzati da soli, Query Optimizer semplicemente li ignorerà. Tuttavia, le colonne a bassa selettività fanno molte volte buoni tasti compositi quando sono accoppiati con una colonna ad alta selettività.

39
Remus Rusanu