Per utilizzare indici per tutte le possibili condizioni di uguaglianza su N
colonne, è necessario C([N/2], N)
indici, cioè N!/([N/2]! * (N - [N/2])!)
si veda questo articolo nel mio blog per le spiegazioni dettagliate:
Si può anche leggere la rigorosa matematica proof dal matematico russo Egor Timoshenko
(aggiornamento: ora in inglese).
Si può, tuttavia, ottenere prestazioni decenti con meno indici utilizzando le seguenti tecniche:
Indice fusione
Se le colonne col1
, col2
e col3
sono selettivi, allora questa query
SELECT *
FROM mytable
WHERE col1 = :value1
AND col2 = :value2
AND col3 = :value3
possono utilizzare tre indici separati su col1
, col2
e col3
, selezionare il 's ROWID
che corrispondono ogni condizione separatamente e li trovano la loro intersezione, come in:
SELECT *
FROM (
SELECT rowid
FROM mytable
WHERE col1 = :value1
INTERSECT
SELECT rowid
FROM mytable
WHERE col2 = :value2
INTERSECT
SELECT rowid
FROM mytable
WHERE col3 = :value3
) mo
JOIN mytable mi
ON mi.rowid = mo.rowid
Bitmap indicizzazione
PostgreSQL
può costruire indici bitmap temporanei in memoria destra durante la query.
Un indice bitmap è un array di bit contiguo piuttosto compatto.
Ogni bit impostato per l'array indica che il correttore tid
deve essere selezionato dalla tabella.
Un tale indice può richiedere ma 128M
di memoria temporanea per una tabella con righe 1G
.
La query seguente:
SELECT *
FROM mytable
WHERE col1 = :value1
AND col2 = :value2
AND col3 = :value3
sarà prima allocare un bitmap zero riempito abbastanza grande per coprire tutte le possibili tid
's nella tabella (che è abbastanza grande per prendere tutti tid
' s dal (0, 0)
alla ultimo tid, non tenendo conto della mancanza di tid
).
Quindi cercherà il primo indice, impostando i bit su 1
se soddisfano la prima condizione.
Quindi eseguirà la scansione del secondo indice, AND
'i bit che soddisfano la seconda condizione con un 1
. Questo lascerà 1
solo per quei bit che soddisfano entrambe le condizioni.
Uguale per il terzo indice.
Infine, selezionerà solo le righe con i valori tid
corrispondenti ai bit impostati.
Gli oggetti tid
verranno recuperati in modo sequenziale, quindi è molto efficiente.
Questa è la risposta corretta. MySQL funziona allo stesso modo e questa tecnica è chiamata "Leftmost Prefixing". Dal manuale MySQL su http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html: "Se la tabella ha un indice a colonne multiple, il prefisso più a sinistra dell'indice può essere utilizzato da l'ottimizzatore per trovare le righe. Ad esempio, se hai un indice di tre colonne su (col1, col2, col3), hai indicizzato le capacità di ricerca su (col1), (col1, col2) e (col1, col2, col3) . " – zombat
Hmm, avrei dovuto saperlo. ;) Molto impressionante, darò uno scatto. –
Potrebbe anche essere necessario a, c, ma dipende da come appaiono le query.Potrebbe anche essere necessario l'indice individuale per coprire lo scenario OR menzionato da Andriyev, non è sicuro. –