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


35

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 buona 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 nella maggior parte dei casi. 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.


@brentozar ha un bel video sugli indici che vale la pena guardare: brentozar.com/sql-server-training-videos/…
DForck42

Risposte:


38

Ciò di cui hai bisogno sono gli indici di copertura , 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 colpiscono il database, quali sono critiche e quali no, con quale frequenza viene eseguito ogni tipo di query, ecc. Ecc. Ecc. bilanciare ciò con il costo di scrittura e aggiornamento di ciascun indice e la strategia di indicizzazione è disponibile. 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 ciascuna colonna possono funzionare, a condizione che ogni colonna abbia un'elevata selettività (molti valori distinti, ognuno dei quali 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 hanno senso per essere indicizzati da soli, Query Optimizer semplicemente li ignorerà. Tuttavia, molte volte le colonne a bassa selettività sono buone chiavi composite quando sono accoppiate a una colonna ad alta selettività.


Grazie Remus. Mi chiedo il vantaggio relativo della creazione di indici multi-colonna mirati (e inclusi), rispetto all'utilizzo di indici separati. Se "funziona abbastanza bene" è abbastanza buono, potrebbe essere OK. (Eliminerà gli indici nei campi a bassa selettività). Questa tecnica dovrebbe aiutare quando non abbiamo accesso al database di produzione e non possiamo indirizzare i nostri indici all'utilizzo effettivo.
RaoulRubin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.