Organizzazione di tabelle e indici
Tabelle e indici vengono archiviati come raccolta di pagine a 8 KB. In questo argomento viene descritta la modalità di organizzazione delle pagine delle tabelle e degli indici.
Organizzazione delle tabelle
Nella figura seguente viene illustrata l'organizzazione di una tabella. Una tabella è contenuta in una o più partizioni, ognuna delle quali include righe di dati in una struttura di heap o di indice cluster. Le pagine dell'heap o dell'indice cluster vengono gestite in una o più unità di allocazione, in base ai tipi di colonna nelle righe di dati.
Partizioni
Le pagine delle tabelle e degli indici sono incluse in una o più partizioni. Una partizione è un'unità di organizzazione dei dati definita dall'utente. Per impostazione predefinita, una tabella o indice dispone di una sola partizione che include tutte le pagine della tabella o dell'indice. La partizione è contenuta in un singolo filegroup. Una tabella o indice con una singola partizione è equivalente alla struttura organizzativa di tabelle e indici nelle versioni precedenti di SQL Server.
Quando una tabella o indice utilizza più partizioni, i dati vengono partizionati orizzontalmente in modo che per i gruppi di righe venga eseguito il mapping in partizioni individuali, in base a una colonna specificata. Le partizioni possono essere inserite in uno o più filegroup nel database. La tabella o indice viene gestito come singola entità logica quando query o aggiornamenti vengono eseguiti sui dati. Per ulteriori informazioni, vedere Tabelle e indici partizionati.
Per visualizzare le partizioni utilizzate da una tabella o indice, utilizzare la vista del catalogo sys.partitions (Transact-SQL).
Tabelle cluster, heap e indici
Nelle tabelle di SQL Server vengono utilizzati due metodi di organizzazione delle pagine di dati all'interno di una partizione:
Le tabelle cluster sono tabelle che includono un indice cluster.
Le righe di dati vengono archiviate con ordinamento basato sulla chiave di indice cluster. L'indice cluster viene implementato come struttura di indice ad albero B che supporta il recupero rapido delle righe in base ai rispettivi valori della chiave di indice cluster. Le pagine di ogni livello dell'indice, incluse le pagine di dati a livello foglia, sono collegate tra loro in un elenco con collegamento doppio. Tuttavia, la navigazione tra i livelli viene eseguito utilizzando i valori chiave. Per ulteriori informazioni, vedere Strutture degli indici cluster.
Gli heap sono tabelle che non includono un indice cluster.
Le righe di dati non vengono archiviate in un ordine specifico. Ciò vale anche per la sequenza delle pagine di dati. Le pagine di dati non sono collegate in un elenco collegato. Per ulteriori informazioni, vedere Struttura degli heap.
Le viste indicizzate hanno la stessa struttura di archiviazione delle tabelle cluster.
Quando un heap oppure una tabella cluster include più partizioni, ogni partizione dispone di un heap oppure di un albero B che include il gruppo di righe per la specifica partizione. Ad esempio, se una tabella cluster include quattro partizioni, sono presenti quattro alberi B, uno per ogni partizione.
Indici non cluster
Gli indici non cluster hanno una struttura di indice ad albero B analoga a quella degli indici cluster, con la differenza che gli indici non cluster non producono alcun effetto sull'ordine delle righe di dati. Il livello foglia include le righe dell'indice. Ogni riga dell'indice include il valore della chiave non cluster, un indicatore di posizione delle righe ed eventuali colonne incluse, o non chiave. L'indicatore di posizione punta alla riga di dati che include il valore della chiave. Per ulteriori informazioni, vedere Strutture degli indici non cluster.
Indici XML
È possibile creare un indice primario e vari indici XML secondari su ogni colonna xml nella tabella. Un indice XML è una rappresentazione suddivisa e persistente dei BLOB XML (Binary Large Objects) nella colonna del tipo di dati xml. Gli indici XML vengono archiviati come tabelle interne. Per visualizzare informazioni relative agli indici XML, utilizzare le viste del catalogo sys.xml_indexes oppure sys.internal_tables.
Per ulteriori informazioni sugli indici XML, vedere Indici su colonne con tipo di dati XML.
Unità di allocazione
Un'unità di allocazione è una raccolta di pagine all'interno di un heap o di un albero B utilizzata per gestire i dati in base al tipo di pagina relativo. Nella tabella seguente sono elencati i tipi di unità di allocazione utilizzati per gestire i dati in tabelle e indici.
Tipo di unità di allocazione |
Utilizzata per gestire |
---|---|
IN_ROW_DATA |
Dati o righe di indice che includono tutti i dati, fatta eccezione per i dati LOB. Le pagine sono di tipo dati oppure indice. |
LOB_DATA |
I dati LOB vengono archiviati in uno o più tra i tipi di dati seguenti: text, ntext, image, xml, varchar(max), nvarchar(max), varbinary(max) oppure tipi CLR definiti dall'utente (CLR UDT). Le pagine sono di tipo testo/immagine. |
ROW_OVERFLOW_DATA |
Dati di lunghezza variabile archiviati in colonne varchar, nvarchar, varbinary, oppure sql_variant che superano il limite di dimensioni riga di 8.060 byte. Le pagine sono di tipo testo/immagine. |
Per ulteriori informazioni sui tipi di pagina, vedere Informazioni su pagine ed extent.
Un heap o un albero B può includere una sola unità di allocazione di ogni tipo in una partizione specifica. Per visualizzare le informazioni sull'unità di allocazione di tabella o di indice, utilizzare la vista del catalogo sys.allocation_units.
Unità di allocazione IN_ROW_DATA
Per ogni partizione utilizzata da una tabella (heap o tabella cluster), indice o vista indicizzata, esiste un'unità di allocazione IN_ROW_DATA costituita da una raccolta di pagine di dati. Questa unità di allocazione include inoltre raccolte aggiuntive di pagine per l'implementazione di ogni indice non cluster e XML definito per la tabella o vista. Le raccolte di pagine in ogni partizione di una tabella, indice o vista indicizzata sono ancorate da puntatori di pagina nella vista di sistema sys.system_internals_allocation_units.
Importante |
---|
La vista di sistema sys.system_internals_allocation_units è riservata per il solo uso interno a Microsoft SQL Server. Non è garantita la compatibilità con le versioni future. |
Ogni partizione di tabella, indice e vista indicizzata include una riga in sys.system_internals_allocation_units identificata in modo univoco da un ID contenitore (container_id). Per l'ID contenitore è presente un mapping uno-a-uno a partition_id nella vista del catalogo sys.partitions che conserva la relazione tra i dati della tabella, dell'indice o della vista indicizzata archiviati in una partizione e le unità di allocazione utilizzate per gestire i dati all'interno della partizione.
L'allocazione delle pagine a una partizione di tabella, indice o vista indicizzata viene gestita da una sequenza di pagine IAM. La colonna first_iam_page in sys.system_internals_allocation_units punta alla prima pagina IAM nella catena che gestisce lo spazio allocato per la tabella, l'indice o la vista indicizzata nell'unità di allocazione IN_ROW_DATA.
sys.partitions restituisce una riga per ogni partizione in una tabella o indice.
Un heap include una riga in sys.partitions con index_id = 0.
La colonna first_iam_page in sys.system_internals_allocations_units punta alla catena IAM per la raccolta di pagine di dati di heap nella partizione specificata. Il server utilizza le pagine IAM per individuare le pagine nelle raccolte delle pagine poiché le pagine non sono collegate tra loro.
Un indice cluster di una tabella o di una vista include una riga in sys.partitions con index_id = 1.
La colonna root_page in sys.system_internals_allocations_units punta al primo livello dell'albero B cluster nella partizione specificata. Il server utilizza l'albero B dell'indice per trovare le pagine di dati nella partizione.
Ogni indice non cluster creato per una tabella o una vista include una riga in sys.partitions con index_id >= 1.
La colonna root_page in sys.system_internals_allocations_units punta al primo livello dell'albero B dell'indice non cluster nella partizione specificata.
Ogni tabella che include almeno una colonna LOB include una riga in sys.partitions con index_id > 250.
La colonna first_iam_page punta alla catena di pagine IAM che gestiscono le pagine nell'unità di allocazione LOB_DATA.
Unità di allocazione ROW_OVERFLOW_DATA
Per ogni partizione utilizzata da una tabella (heap o tabella cluster), indice o vista indicizzata, esiste un'unità di allocazione ROW_OVERFLOW_DATA. Questa unità di allocazione include zero (0) pagine finché una riga di dati con colonne di lunghezza variabile (varchar, nvarchar, varbinary, oppure sql_variant) nell'unità di allocazione IN_ROW_DATA supera il limite delle dimensioni della riga di 8 KB. Quando il limite di dimensioni viene raggiunto, SQL Server sposta la colonna con la larghezza massima dalla riga su una pagina nell'unità di allocazione ROW_OVERFLOW_DATA. Un puntatore a 24 byte a questi dati all'esterno di righe viene mantenuto sulla pagina originale.
Le pagine text/image nell'unità di allocazione ROW_OVERFLOW_DATA sono gestite in modo analogo alle pagine nell'unità di allocazione LOB_DATA, ovvero tramite una catena di pagine IAM.
Unità di allocazione LOB_DATA
Quando una tabella o un indice include uno o più tipi di dati LOB, un'unità di allocazione LOB_DATA per partizione viene allocata per la gestione dell'archiviazione dei dati. I tipi di dati LOB includono text, ntext, image, xml, varchar(max), nvarchar(max), varbinary(max) e tipi CLR definiti dall'utente.
Esempio di partizione e di unità di allocazione
L'esempio seguente restituisce dati di partizione e di unità di allocazione per due tabelle: DatabaseLog, un heap con dati LOB e nessun indice non cluster e Currency, una tabella cluster priva di dati LOB e un indice non cluster. Entrambe le tabelle includono una singola partizione.
USE AdventureWorks2008R2;
GO
SELECT o.name AS table_name,p.index_id, i.name AS index_name , au.type_desc AS allocation_type, au.data_pages, partition_number
FROM sys.allocation_units AS au
JOIN sys.partitions AS p ON au.container_id = p.partition_id
JOIN sys.objects AS o ON p.object_id = o.object_id
JOIN sys.indexes AS i ON p.index_id = i.index_id AND i.object_id = p.object_id
WHERE o.name = N'DatabaseLog' OR o.name = N'Currency'
ORDER BY o.name, p.index_id;
Set di risultati. Si noti che la tabella DatabaseLog utilizza tutti e tre i tipi di unità di allocazione, in quanto include sia tipi dati sia tipi di pagina text/image. La tabella Currency non include dati LOB, ma l'unità di allocazione necessaria per la gestione delle pagine di dati. Se la tabella Currency viene in seguito modificata per includere una colonna di tipo di dati LOB, un'unità di allocazione LOB_DATA viene creata per gestire i dati stessi.
table_name index_id index_name allocation_type data_pages partition_number
----------- -------- ----------------------- --------------- ----------- ------------
Currency 1 PK_Currency_CurrencyCode IN_ROW_DATA 1 1
Currency 3 AK_Currency_Name IN_ROW_DATA 1 1
DatabaseLog 0 NULL IN_ROW_DATA 160 1
DatabaseLog 0 NULL ROW_OVERFLOW_DATA 0 1
DatabaseLog 0 NULL LOB_DATA 49 1
(5 row(s) affected)
Vedere anche