L'aggiunta dell'indice sulla colonna di bit rallenta significativamente gli inserti?


11

Ho un tavolo con circa da 1 a 5 milioni di dischi. Una piccola parte di quei record ha una colonna di bit impostata su "TRUE". È necessario trovare rapidamente quei record. Penso che l'indice possa accelerare la ricerca su questa colonna, ma temo gli INSERTI. Da qui la mia domanda.

Il database funziona come una sorta di data warehouse, quindi ci sono molti SELECT e INSERT piccoli (fino a 10-20 al giorno) ma abbastanza grandi (fino a 200 mila record contemporaneamente). Temo per un tempo più lungo di tali importazioni nel database.


5
Quale versione di SQL Server? Se 2008+ suona come un indice filtrato potrebbe essere quello che ti serve.
Martin Smith,

SQL Server 2005
marioosh,

1
Potresti dividere la tabella (aggiungi una nuova tabella con una sola colonna, il PK della tabella, che verrebbe popolato solo con quelle righe in cui la colonna di bit è vera - alla fine potresti persino rimuovere la colonna di bit.) Un indice vista funzionerebbe, anche nel 2005, con la mancanza di indici parziali.
ypercubeᵀᴹ

fai attenzione con la vista indicizzata, poiché hai menzionato che hai 10-20 inserti di grandi dimensioni al giorno, la manutenzione della vista indicizzata potrebbe superare il vantaggio del miglioramento delle prestazioni. non credo che nessuna delle funzionalità predefinite di SQL 2005 sia possibile utilizzare per migliorare la propria situazione. ma se elenchiamo la struttura della tabella corrente e l'indice esistente, potremmo trovare qualche progetto alternativo.
Anup Shah,

Risposte:


8

Un indice su un po 'per 1 milione di record è inutile. L'ottimizzatore non lo userà mai, pagherai solo per mantenerlo. Un'alternativa molto migliore è quella di aggiungere questo bit come chiave all'estrema sinistra dell'indice cluster.

Ma farò uno scatto al buio e suppongo che quello che hai sia un modello di coda: i record vengono rilasciati nella tabella con il bit impostato su 'TRUE' (cioè. per questi record, esegue alcune elaborazioni e aggiorna il bit a FALSE. Questo è un modello onnipresente, anche conosciuto affettuosamente come "modello di ricetta per il disastro delle prestazioni". Consiglierei di inserire i record nella tabella e di rilasciare una notifica (potrebbe essere semplice come l'ID record appena inserito), allo stesso tempo, in una coda . Vedere Utilizzo delle tabelle come code .


1
Non vedo alcun punto utile nel mettere la colonna di bit sul lato più a sinistra in quanto non sappiamo che potrebbero avere altre colonne di filtro con un utente ad alto cardinale. finora ho visto la colonna BIT è l'ultima scelta nell'indice cluster. ma sì, +1 per il bel riferimento di "Usare la tabella come code".
Anup Shah,

2
In realtà ho eseguito un test e sì, utilizzerà l'indice. Creare una tabella (Identità id, bit myBit) aggiungere 100 righe in cui il bit è 0 e 2000000 in cui il bit è 1. Assicurarsi che le statistiche siano aggiornate (se necessario) ed eseguire una query su myBit = 0 e verrà utilizzato l'indice.
Kenneth Fisher,

@KennethFisher ad eccezione del fatto che nel tipico modello ad alta velocità di inserire TRUE / aggiornamento a FALSE immediatamente le statistiche saranno sempre obsolete. Se preferisci giocare alla roulette russa con l'ottimizzatore piuttosto che fare un design chiaro, otterrai ciò che meriti ...
Remus Rusanu,

"non lo userà mai" afferma questa affermazione per il 99% dei casi, ma non sappiamo in quale caso si trovi l'OP. Ho indicizzato con successo il bit. Esistono casi d'uso.
usr

domanda: la risposta qui è errata, in particolare> "Quando si indicizza un campo bit (o un intervallo ristretto), si riduce solo il set di lavoro del numero di righe corrispondenti a quel valore. Se si dispone di un piccolo numero di righe corrispondenti ridurrebbe molto il tuo set di lavoro . Per un gran numero di righe con distribuzione 50/50, si potrebbe acquistare un guadagno di prestazioni molto ridotto rispetto a mantenere aggiornato l'indice ". In tal caso, un indice su un bit che corrisponde all'1% dei record eviterebbe la necessità di scansionare il 99% di 1 milione per una spinta significativa?
drzaus,

2

Come ha detto @MartinSmith se si aggiorna mai a SQL 2008, un indice filtrato sarebbe la soluzione perfetta. Tuttavia, nel frattempo, come caso generale, QUALUNQUE indice aggiunto aumenterà il tempo di caricamento. Piccoli indici meno di quelli grandi.

Una cosa che vorrei guardare è se hai un indice esistente che può essere modificato. Supponendo che le tue query esistenti stiano utilizzando un determinato indice, quindi l'aggiunta della colonna di bit alla fine di tale indice dovrebbe avere un effetto minimo sugli inserti e l'effetto positivo che stai cercando sulle tue query.

La prossima cosa da guardare è "Ho già molti indici?" Non esiste una regola rigida e veloce su ciò che è "molto", ma di solito vado in base a una regola di 10 indici che è il limite a meno che non abbia VERAMENTE bisogno di uno nuovo.

Ultimo pensiero, testalo su un'istanza di test. Imposta una tabella con alcuni milioni di righe, esegui il carico su di esso, aggiungi il tuo indice quindi esegui nuovamente il carico e vedi se noti un aumento significativo del tempo di caricamento.

Solo tu puoi veramente decidere cosa sia "significativo". Ho macchine in cui l'aggiunta di 5 minuti al tempo di caricamento è "significativa" e altre in cui ho potuto vedere aumentare di un paio d'ore in sicurezza.

MODIFICARE:

Un'altra opzione è quella di partizionare la tabella. Potrebbe non essere necessario utilizzare una vista partizionata se non si utilizza l'edizione Enterprise ma anche in questo caso dovrebbe essere di aiuto. Metti i tuoi bit 0 in una partizione e i bit 1 in un'altra. Supponendo che tu stia inserendo solo una versione o l'altra, potresti persino accelerare gli inserti.

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.