Problema
Facciamo un po' di chiarezza, perché questo è un problema comune, un problema serio per ogni azienda che utilizza SQL Server.
Questo problema e la necessità di CREATE CLUSTERED INDEX sono fraintesi.
D'accordo sul fatto che avere un indice cluster permanente è meglio che non averne uno. Ma non è questo il punto, e porterà comunque a una lunga discussione, quindi mettiamolo da parte e concentriamoci sulla domanda postata.
Il punto è che hai una notevole frammentazione nell'Heap . Continui a chiamarlo "tabella", ma non esiste una cosa del genere a livello di archiviazione fisica dei dati o DataStructure. Un tavolo è un concetto logico, non fisico. È una raccolta di DataStructures fisiche. La collezione è una delle due possibilità:
-
Heap
più tutti gli indici non cluster
più catene di testo/immagini -
o un Indice cluster
(elimina l'Heap e uno Indice non cluster)
più tutti gli indici non cluster
più catene di testo/immagine.
I cumuli si frammentano gravemente; più inserimenti/elimina/aggiornamenti sono intervallati (casuali), maggiore è la frammentazione.
Non c'è modo di ripulire l'Heap, così com'è. MS non fornisce una struttura (altri fornitori lo fanno).
Soluzione
Tuttavia, sappiamo che Create Clustered Index riscrive e riordina completamente l'heap. Il metodo (non un trucco), quindi, è quello di creare un indice cluster solo allo scopo di deframmentare l'heap , e rilascialo in seguito. Hai bisogno di spazio libero nel db di table_size x 1.25.
Già che ci sei, usa FILLFACTOR per ridurre il futuro frammentazione. L'heap occuperà quindi più spazio allocato, consentendo futuri inserimenti, eliminazioni ed espansioni di righe dovute agli aggiornamenti.
Nota
-
Tieni presente che ci sono tre Livelli di frammentazione; questo riguarda solo il livello III, la frammentazione all'interno dell'heap, causata da Mancanza di un indice cluster
-
Come attività separata, in un altro momento, potresti voler contemplare l'implementazione di un indice cluster permanente, che elimina del tutto la frammentazione ... ma è separato dal problema pubblicato.
Risposta al commento
Non proprio. Non lo chiamerei "limite".
-
Il metodo che ho fornito per eliminare la frammentazione nell'heap è creare un indice cluster, e quindi rilasciarlo. Cioè. temporaneamente, il cui unico scopo è correggere la Frammentazione.
-
L'implementazione di un indice cluster sul tavolo (permanentemente) è una soluzione molto migliore, perché riduce complessivamente Frammentazione (la DataStructure può ancora essere frammentata, fare riferimento a informazioni dettagliate nei collegamenti seguenti), che è molto inferiore alla frammentazione che si verifica in un heap.
-
Ogni tabella in un database relazionale (tranne le tabelle "pipe" o "queue") dovrebbe avere un indice cluster, al fine di sfruttare i suoi vari vantaggi.
-
L'indice cluster dovrebbe trovarsi su colonne che distribuiscono i dati (evitando conflitti INSERT), non essere mai indicizzato su una colonna monotonicamente crescente, come Record ID , che garantisce un INSERT Hot Spot nell'ultima pagina.
-
In MS SQL e Sybase ASE, ci sono tre Livelli di frammentazione e, all'interno di ogni livello, diversi Tipi . Tieni presente che quando si ha a che fare con la frammentazione, dobbiamo concentrarci su DataStructures, non sulle tabelle (una tabella è una raccolta di DataStructures, come spiegato sopra). I livelli sono:
-
Livello I • Struttura di dati extra
Al di fuori della DataStructure interessata, attraverso o all'interno del database. -
Livello II • Struttura dei dati
All'interno della DataStructure interessata, sopra le pagine (in tutte le pagine)
Questo è il livello più frequentemente affrontato dai DBA. -
Livello III • Pagina
All'interno della DataStructure interessata, all'interno delle Pagine
Questi collegamenti forniscono tutti i dettagli sulla frammentazione. Sono specifici di Sybase ASE, tuttavia, a livello strutturale, le informazioni si applicano a MS SQL.
Nota che il metodo che ho indicato è di livello II, corregge la frammentazione di livello II e III.