SQL Server 2008 - Partizionamento e indici cluster


16

Consentitemi quindi di prefazione dicendo che non ho il controllo totale sulla mia progettazione di database, quindi molti aspetti del sistema attuale non possono essere modificati ai fini di questo scenario.

I commenti su come dovremmo ripensare gli aspetti del progetto sono probabilmente corretti ma inutili :)

Ho una tabella molto grande, larga circa 150 campi e circa 600 m di file, che guida un gran numero di processi. Questo si trova in una situazione di data warehouse, quindi non abbiamo NESSUN aggiornamento / inserto al di fuori del processo di caricamento pianificato, quindi è fortemente indicizzato.

È stata presa la decisione di provare a partizionare questa tabella e ho alcune preoccupazioni riguardo all'indicizzazione di una tabella partizionata. Non ho alcuna esperienza con il partizionamento, quindi qualsiasi input o link sono apprezzati. Non sono riuscito a individuare in modo specifico ciò che sto cercando su BOL o msdn.

Attualmente ci raggruppiamo in un campo che chiameremo IncidentKeyche è un varchar(50)e non unico: potremmo avere tra 1 e 100 record con lo stesso IK(nessun commento, per favore). Riceviamo spesso nuovi dati su vecchi IncidentKeyrecord, quindi non sono neanche sequenziali.

Comprendo che devo includere il mio campo di partizione IncidentDate, nella mia chiave di indice cluster affinché la partizione funzioni correttamente. Sto pensando che sarebbe IncidentKey, IncidentDate.

La domanda è: come funzioneranno i meccanici di un indice cluster su una chiave a 2 parti in una tabella partizionata, se un record in una "nuova" partizione dovrebbe essere prima di un record in una "vecchia" partizione dell'indice cluster?

Ad esempio, ho 5 record:

IncidentKey    Date

ABC123        1/1/2010
ABC123        7/1/2010
ABC123        1/1/2011
XYZ999        1/1/2010
XYZ999        7/1/2010

Se ottengo un nuovo record ABC123, 2/1/2011perché dovrà essere nell'indice cluster PRIMA XYZ999, 1/1/2010 . Come funziona?

Sto assumendo frammentazione e puntatori, ma non riesco a trovare alcuna informazione sulla memoria fisica e sulla configurazione degli indici cluster non partizionati su tabelle partizionate con chiavi a doppia parte.


Perché è stata presa la decisione di partizionare la tabella? Quali sono i vantaggi attesi dal partizionamento?
Remus Rusanu,

@Remus - In realtà lo sto facendo come test, quindi avremo una versione partizionata e una non partizionata. Il vantaggio previsto è una riduzione dei tempi di caricamento e dei tempi di costruzione dell'indice. Facciamo operazioni ETL mensili che durano circa una settimana e la speranza è che questo riduca in modo significativo questo tempo. Abbiamo anche una distribuzione di circa 3 TB che speriamo di ridurre con questo.
JNK,

Risposte:


18

Una tabella partizionata è molto più simile a una raccolta di singole tabelle cucite insieme. Quindi, nel tuo esempio di clustering IncidentKeye partizione per IncidentDate, dire che la funzione di partizionamento divide le tabelle in due partizioni in modo che 1/1/2010 sia nella partizione 1 e 7/1/2010 sia la partizione due. I dati saranno disposti su disco come:

Partition 1:
IncidentKey    Date
ABC123        1/1/2010
ABC123        1/1/2011
XYZ999        1/1/2010

Partition 2:
IncidentKey    Date
ABC123        7/1/2010
XYZ999        7/1/2010

A un livello basso ci sono davvero due set di righe distinti. È il Query Processor che dà l'illusione di una singola tabella creando piani che cercano, scansionano e aggiornano tutti i set di righe contemporaneamente.

Qualsiasi riga in qualsiasi indice non cluster avrà la chiave di indice cluster a cui corrisponde, diciamo ABC123,7/1/2010. Poiché la chiave dell'indice cluster contiene sempre la colonna della chiave di partizionamento, il motore saprà sempre in quale partizione (set di righe) dell'indice cluster cercare questo valore (in questo caso, nella partizione 2).

Ora, ogni volta che hai a che fare con il partizionamento, devi considerare se i tuoi indici NC saranno allineati (l'indice NC è partizionato esattamente come l'indice cluster) o non allineato (l'indice NC non è partizionato o partizionato diversamente dall'indice cluster) . Gli indici non allineati sono più flessibili, ma presentano alcuni svantaggi:

L'uso di indici allineati risolve questi problemi, ma comporta una serie di problemi, poiché questa opzione di progettazione fisica e di archiviazione si increspa nel modello di dati:

  • gli indici allineati indicano che non è più possibile creare / applicare vincoli univoci (ad eccezione della colonna di partizionamento)
  • tutte le chiavi esterne che fanno riferimento alla tabella partizionata devono includere la chiave di partizionamento nella relazione (poiché la chiave di partizionamento è, a causa dell'allineamento, in ogni indice) e questo a sua volta richiede che tutte le tabelle che fanno riferimento alla tabella partizionata contengano il valore della colonna chiave di partizionamento. Pensa a Order-> OrderDetails, se Orders ha OrderID ma è partizionato da OrderDate, OrderDetails deve contenere non solo OrderID, ma anche OrderDate, al fine di dichiarare correttamente il vincolo di chiave esterna.

Questi effetti che ho riscontrato raramente all'inizio di un progetto che distribuisce il partizionamento, ma esistono e hanno gravi conseguenze.

Se pensate che gli indici allineati siano un caso raro o estremo, considerate questo: in molti casi la pietra angolare dell'ETL e delle soluzioni di partizionamento è il rapido passaggio da una tabella di staging all'altra. Le operazioni di commutazione richiedono indici allineati.

Oh, un'altra cosa: tutto il mio argomento sulle chiavi esterne e l'effetto a catena di aggiungere il valore della colonna di partizionamento ad altre tabelle si applica ugualmente ai join .


Perfetto, questo è esattamente quello che stavo cercando. Dovremo usare indici allineati b / c lo scambio è una parte del sorteggio per quello che vogliamo fare con questo. Facciamo anche un sacco di funzioni aggregate raggruppando su quel IncidentKeycampo, che penso che questo ostacolerà seriamente. Apprezzo tutti i dettagli!
JNK,

Di solito i vantaggi delle operazioni dello switch di partizione superano tutti i problemi.
Remus Rusanu,

Questa è la nostra speranza, vedremo presto!
JNK,

9

Quando un indice cluster ha più partizioni, ogni partizione ha una struttura B-tree che contiene i dati per quella specifica partizione. Ad esempio, se un indice cluster ha quattro partizioni, ci sono quattro strutture B-tree; uno in ogni partizione. Ref. Strutture di indice cluster

Linee guida speciali per gli indici partizionati

È possibile ricostruire partizioni specifiche di un indice partizionato.

per esempio

ALTER INDEX IX_TransactionHistory_TransactionDate
ON Production.TransactionHistory
REBUILD Partition = 5;
GO

+1 Per il link, avevo letto le linee guida speciali ma ho perso quel paragrafo. Domanda di follow-up: facciamo molta aggregazione sul IncidentKeycampo, pensi che ciò influirebbe negativamente sulle prestazioni (mi rendo conto che dovrò ancora fare dei test)?
JNK,

Non conosco tutte le tue circostanze specifiche ma mi sembra che potresti stare meglio con il partizionamento di IncidentDate?
Mitch Wheat,

Stiamo partizionando alla data, ma la chiave cluster è attiva IncidentKey- facciamo un sacco di join su questo ed è una specie di cosa istituzionale che usiamo per raggruppare. Sto testando una chiave alternativa, ma per ora questo è quello che devo usare.
JNK,
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.