tabele Heap în SQL Server

în ultimul post al acestei serii de blog, am discutat ce un index b-copac a fost și a explicat pe scurt istoria sa.

înainte de a ne arunca cu capul în indici care utilizează SQL Server, este important să se stabilească fundamentul structurilor de date. Tabelul cel mai de bază pe care îl puteți crea este o grămadă. O grămadă este o structură nesortată de pagini care nu sunt legate între ele.

când trebuie să utilizați grămezi?

recomandarea de bune practici este de a evita grămezi SQL Server, în cele mai multe cazuri. Kimberly Tripp explică unele dintre motivele și dezbaterea aici, dar voi acoperi la nivel înalt. Heaps, fiind cea mai de bază structură de stocare, lipsește caracteristici care îmbunătățesc performanța pentru sarcini de lucru normale (OLTP). Unii susțin că grămezile sunt mai bune pentru operațiunile de extragere, transformare și încărcare (ETL), deoarece există mai puține pagini de întreținut în timpul operațiilor de scriere (actualizare/Inserare/ștergere). Mai exact, grămezile pot fi mai rapide decât un index B-tree dacă apar împărțiri de pagini și multe niveluri ale indexului trebuie actualizate. În plus, identificatorul rândului (RID), discutat mai jos, este de numai 8 octeți. Acest lucru poate funcționa mai bine decât un index pus în cluster cu o mulțime de coloane cheie, deoarece indexurile care nu sunt grupate trebuie să stocheze cheia pusă în cluster sau să scape pentru fiecare rând indexat. De obicei, vă recomand să utilizați un index grupat (mai mult pe indici grupați pe măsură ce continuăm această serie), mai degrabă decât o grămadă, dar, dacă le folosiți, folosiți-le numai atunci când ați dovedit că vor fi mai eficiente decât un index grupat. După ce am discutat despre structura unui heap, voi sublinia preocupările de performanță ale utilizării grămezilor.

structura Heap

o heap este o grupare de pagini nesortate care nu sunt legate. Anatomia paginii este în afara domeniului de aplicare pentru această serie, deoarece toate tipurile de tabele indexate și neindexate utilizează aceeași structură a paginii, dar vă încurajez să consultați aici și aici pentru a afla mai multe.

un heap este format din una sau mai multe pagini index allocation map (IAM) care indică paginile de date care alcătuiesc heap-ul. Singura excepție de la acest lucru este atunci când aveți un rând care a fost actualizat și nu mai putea încăpea în pagina sa. În acest caz, obțineți un indicator de redirecționare către rândul care a fost mutat într-o pagină existentă cu spațiu sau o pagină nouă. Este posibil să produceți un lanț de înregistrări de expediere dacă rândul continuă să aibă nevoie de relocare prin operațiuni ulterioare.

heap-structure-1

referință imagine: MSDN

o grămadă are un rând în sys.partițiile pe partiție și index_id-ul său vor fi egale cu zero. În această înregistrare, first_iam_page indică prima dintre paginile index allocation map (iam). O pagină iam mapează paginile pentru fiecare unitate de alocare și gestionează 4 bucăți GB din tabel. Unitățile de alocare includ:

  1. IN_ROW_DATA unitate de alocare
  2. LOB_DATA unitate de alocare
  3. ROW_OVERFLOW_DATA unitate de alocare

pagina IAM conține antetul standard de 96 de octeți urmat de antetul IAM. Antetul IAM începe cu opt sloturi pentru alocări mixte și apoi o hartă de biți de 8000 de octeți pentru a localiza extensiile uniforme alocate tabelului.

o măsură mixtă este una care conține pagini din mai multe tabele. Acest lucru este, de asemenea, menționată ca o măsură comună. Scopul unei întinderi mixte este de a economisi spațiu cu tabele mai mici de 64 KB. O măsură uniformă este una în care toate paginile din măsură aparțin acelui singur tabel.

mixed-extent

referință imagine: măsura

pentru a investiga pagina noastră IAM, mai întâi trebuie să o localizăm.

DBCC IND (‘demo’,’dbo.demo’,1)

dbcc-ind

cu DBCC IND, avem 17 pagini de date și 1 pagină IAM. Paginile IAM nu se auto-referențiază, prin urmare Iamfid (id fișier IAM) și IAMPID (id pagină iam) sunt nule. Aceasta înseamnă că pagina noastră IAM se află în ID-ul fișierului (PageFID) 1 și este ID-ul paginii (PagePID) 297. Pagina DBCC ne va permite să vizualizăm pagina noastră IAM.

DBCC TRACEON(3604);

pagina DBCC (‘demo’,1,297,3);

dbcc-page-iam

în galben există opt alocări de o singură pagină în măsura noastră mixtă. În portocaliu extensiile uniforme sunt afișate în intervale.

implicații de performanță

efectuarea diferitelor operații de limbaj de manipulare a datelor (DML) pe un heap are aceste efecte.

  • Inserare – rânduri noi pot fi plasate în prima pagină disponibilă cu spațiu suficient. Deci, ori de câte ori se introduce un rând nou, acesta va fi probabil adăugat la ultima pagină.
  • actualizare – rândurile pot rămâne pe aceeași pagină dacă se încadrează în pagină după actualizare, dacă nu vor fi eliminate din pagina curentă și plasate pe prima pagină disponibilă cu suficient spațiu și un indicator de redirecționare este scris în pagina sa originală.
  • DELETE – datele nu sunt suprascrise, spațiul este doar marcat ca fiind disponibil pentru reutilizare. Acest lucru poate determina tabelul dvs. să consume mult mai mult spațiu pe disc decât este necesar.
  • selectare – o scanare a tabelului pe întregul tabel va trebui citită pentru majoritatea interogărilor. Excepția de la acest lucru este atunci când există un indice adecvat non-grupate disponibile. Vom discuta indici non-grupate mai târziu în această serie.

Citește

fără nici un index de sprijin, o grămadă necesită o Scanare completă tabel pentru orice interogare. Acest lucru se datorează faptului că structura fizică nu este sortată și nu există nicio legătură de pagină pentru a sprijini scanările de gamă.

SET statistici IO pe

DBCC IND (‘demo’,’dbo.demo’,1)

selectați COUNT(*)
din dbo.demo

repetarea comenzii noastre DBCC IND de sus ne amintește că avem 18 pagini pentru acest tabel. 17 pagini de date și 1 pagină IAM.

–rezultate DBCC Ind eliminate, deoarece este deja afișat mai sus.
-18 rezultatul rândului, indică 18 pagini.

(18 rânduri afectate)
execuția DBCC finalizată. Dacă DBCC a imprimat mesaje de eroare, contactați administratorul de sistem.

număr de rânduri
—-
5031
(1 rândul(rândurile) afectat (e))

tabel ‘Demo’. Numărul de scanare 1, Citește logic 17, citește fizic 0, citește înainte 0, citește logic lob 0, citește fizic lob 0,citește lob înainte 0.
(1 rând (e) afectate)

notați cele 17 citiri logice din interogarea noastră. Acest lucru se datorează faptului că pagina IAM nu este numărată în metrica de citire logică și am efectuat o Scanare completă a tabelului cu 18 pagini.

scrie și transmite indicii

după cum sa menționat mai sus, inserturi și șterge sunt destul de drept înainte. O inserție apare pe prima pagină cu spațiu disponibil, chiar dacă aceasta înseamnă crearea unei noi pagini. Ștergerile sunt efectuate prin eliminarea spațiului ocupat de rând.

actualizările sunt locul în care lucrurile merg în jos pentru grămezi. Atunci când un tip de date lungime fixă este actualizat actualizarea va avea loc în loc. Dacă un tip de date cu lungime variabilă este actualizat și lungimea a crescut, există șansa ca rândul să nu mai încapă în aceeași pagină. Când rândul nu se mai potrivește, un indicator de redirecționare este pus în spațiul în care a fost rândul original și rândul este mutat într-o pagină nouă. Acest proces are un impact negativ asupra performanței citirii. Să demonstrăm.

inițial toate înregistrările noastre în dbo.tabelul demo conținea VARCHARs cu 9 șiruri de caractere.

selectați TOP 5 *
din dbo.demo

date tabel demo

pentru a crea unele indicii înainte vom actualiza toate rândurile noastre și de a crește lungimea coloanei varLen.

actualizare dbo.demo
set varLen = replică (‘a’,100)

acum avem 95 de pagini în grămada noastră, deoarece toate rândurile noastre au fost mutate în pagini noi cu indicatoare înainte lăsate în urmă.

DBCC IND (‘demo’,’dbo.demo’,1)

dbcc-output-1

după cum vă puteți imagina, cu grămezi care necesită scanări complete ale tabelelor, va trebui să citim mult mai multe pagini pentru aceeași cantitate de înregistrări acum.

SET statistici IO pe

selectați COUNT (*)
din dbo.demo
(1 rând (e) afectate)

tabel ‘Demo’. Numărul de scanare 1, Citește logic 4405, citește fizic 0, citește înainte 0, citește logic lob 0, citește fizic lob 0,citește lob înainte 0.

citirile noastre au crescut drastic, deoarece paginile originale trebuiau citite și apoi indicatoarele înainte trebuiau urmate. Impactul performanței și risipa de spațiu în memorie și pe disc este motivul pentru care avem nevoie de indexuri grupate.

data viitoare

structura de date heap nu este un index și este adesea cea mai slabă structură de date pentru tabelele dvs. din SQL Server. Am acoperit-o astăzi ca o bază de înțelegere care va fi utilă pe măsură ce discutăm indicii. În următoarea parte a acestei serii, indexurile grupate, o structură arborescentă B+pentru datele din tabel, vor fi acoperite.

Lasă un răspuns

Adresa ta de email nu va fi publicată.