Ho bisogno di separare gli indici per ogni tipo di query, o sarà un lavoro di indice a più colonne?

dba.stackexchange https://dba.stackexchange.com/questions/197

  •  16-10-2019
  •  | 
  •  

Domanda

I po 'conosco la risposta a questa domanda già, ma mi sento sempre come se non v'è più che ho bisogno di far salire sul tema.

La mia comprensione di base è che in linea generale, un unico indice che solo include tutti i campi si potrebbe essere eseguendo la query / ordinamento su in un dato momento non è probabile che sia utile, ma ho visto questo tipo di cose. Come in, qualcuno ha pensato, "Beh, se abbiamo appena messo tutta questa roba in un indice, il database può essere utilizzato per trovare ciò di cui ha bisogno", senza aver mai visto un piano di esecuzione per alcuni dei in esecuzione query effettivo.

Immaginate un tavolo in questo modo:

id int pk/uid
name varchar(50)
customerId int (foreign key)
dateCreated datetime

I potrebbe vedere un unico indice tra cui i campi name, customerId e dateCreated.

Ma la mia comprensione è che tale indice non sarebbe stato utilizzato in una query come, ad esempio:

SELECT [id], [name], [customerId], [dateCreated]
   FROM Representatives WHERE customerId=1 
   ORDER BY dateCreated

Per query di una, mi sembra che un'idea migliore sarebbe un indice tra cui i campi customerId e dateCreated, con il campo customerId essere 'prima'. Ciò creerebbe un indice che avrebbe i dati organizzati in modo tale che un questa query potrebbe trovare rapidamente ciò di cui ha bisogno -. Nell'ordine di cui ha bisogno

Un'altra cosa che vedo, forse come spesso come il primo, è singoli indici su ogni campo; così, uno ciascuno sui campi name, customerId e dateCreated.

A differenza del primo esempio, questo tipo di disposizione pare talvolta almeno essere parzialmente utile; piano di esecuzione della query può mostrare che almeno che sta utilizzando l'indice sul customerId per selezionare i record, ma non è con l'indice con il campo dateCreated per ordinare loro.


So che questo è un ampio domanda, perché la risposta specifica a qualsiasi richiesta particolare in un particolare insieme di tabelle di solito è di vedere ciò che il piano di esecuzione dice che sta andando a fare, e altrimenti prendere le specifiche del tavolo (s) e le query in considerazione. Inoltre, so che dipende da quanto spesso una query potrebbe essere eseguito in contrasto con il sovraccarico di mantenimento di un determinato indice per esso.

Ma suppongo quello che sto chiedendo è come un generale 'punto di partenza' per gli indici, fa l'idea di avere indici specifici per specifiche, le query di frequente tirato e campi nel WHERE o clausole ORDER BY senso?

È stato utile?

Soluzione

Hai ragione in quanto la vostra query di esempio non utilizzare tale indice.

Il pianificatore query considerare l'utilizzo di un indice, se:

  • tutti i campi contenuti in esso viene fatto riferimento nella query
  • alcuni dei campi a partire dall'inizio si fa riferimento

Non sarà in grado di fare uso di indici che iniziano con un campo non utilizzato dalla query.

Così, per il tuo esempio:

SELECT [id], [name], [customerId], [dateCreated]
   FROM Representatives WHERE customerId=1 
   ORDER BY dateCreated

avrebbe preso in considerazione indici quali:

[customerId]
[customerId], [dateCreated]
[customerId], [dateCreated], [name]

, ma non:

[name], [customerId], [dateCreated]

Se è trovato sia [customerId] e [customerId], [dateCreated], [name] la sua decisione di preferire uno sopra l'altro dipenderebbe le statistiche dell'indice che dipendono stime della bilancia dei dati nei campi. Se [customerId], [dateCreated] sono stati definiti dovrebbe preferire che sugli altri due a meno che non si dà un suggerimento indice specifico in senso contrario.

Non è raro vedere un indice definito per ogni campo nella mia esperienza sia, anche se questo è raramente ottimale la gestione in più necessario per aggiornare gli indici di inserimento / aggiornamento, e lo spazio aggiuntivo necessario per la memorizzazione, è sprecato quando non può mai abituarsi la metà di loro -. ma a meno che il DB vede carichi scrittura pesante le prestazioni non sta andando a puzzare male anche con gli indici in eccesso

indici specifici per frequenti richieste che altrimenti sarebbero lento a causa di tabella o la scansione indice è generalmente una buona idea, anche se non esagerare, come si potrebbe essere lo scambio di una problema di prestazioni per un altro. Se fate definire [customerId], [dateCreated] come un indice, per esempio, si ricordi che il pianificatore di query sarà in grado di usarlo per le query che userebbero un indice su un solo [customerId] se presente. Durante l'utilizzo di solo [customerId] sarebbe leggermente più efficiente rispetto utilizzando l'indice composto questo può essere mitigata da finire con l'avere due indici che competono per lo spazio nella RAM invece di uno (anche se l'intera normali attacchi set di lavoro facilmente in RAM questa competizione memoria aggiuntiva non possono essere un problema).

Altri suggerimenti

Per rispondere alla tua domanda iniziale, sì, gli indici devono essere progettati in tutto il query , non solo il tabella . Ordine dei campi nell'indice è di vitale importanza. La progettazione di un unico indice per essere ottimale per più query è più difficile, e si dovrà fare compromessi.

Per quanto riguarda il secondo punto, si, un gruppo di indici su singole singoli campi è fastidiosamente comune. Vedo tutto il tempo nel mio ambiente, e il suo solito una bandiera rossa per me che il team di sviluppo non ha funzionato con un DBA per la progettazione di indici appropriati.

La mia strategia per gli indici di progettazione, è all'indice:

  • I campi utilizzati in WHERE (in ordine di selettività)
  • I campi utilizzati in ORDER BY
  • Includere altri campi (se necessario) per fare un indice di copertura

Così, per il tuo esempio:

SELECT [id], [name], [customerId], [dateCreated]
   FROM Representatives WHERE customerId=1 
   ORDER BY dateCreated

I probabilmente progettare un indice su (CustomerID, DateCreated) CONTENERE (id, nome). Questo indice copre significa la query non ha mai a colpire la tabella originale, notevolmente migliorando le prestazioni.

Questo esempio è quasi anche semplice, però. Un indice naif solo (CustomerID) si comporta altrettanto bene (assumendo che ogni cliente ha un solo rappresentante, così sarà richiesto un solo segnalibro dinamico alla tabella). Inoltre potrebbe anche essere utile per fare in realtà un cluster indice su (CustomerID, ID), a seconda di ciò che gli altri query eseguite contro il tavolo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a dba.stackexchange
scroll top