Utilizarea indicilor de acoperire
Nu este întotdeauna necesar ca, atunci când se utilizează indexuri care nu sunt grupate, SQL Server să preia întregul șir în a doua etapă. Această situație apare atunci când un index non-clustered include toate datele de tabel pe care SQL Server trebuie să le execute. Când se întâmplă acest lucru, numim acoperirea indexului, deoarece acest index acoperă întreaga interogare. Indicii de acoperire pot spori semnificativ performanța interogărilor; Acest lucru este ușor de văzut pe cele două planuri de interogare din exemplul anterior. În astfel de solicitări, costul operatorilor care extrag liniile de date necesare este de 97% din costul total al cererii. Cu alte cuvinte, cererea fără această operațiune va fi executată de 32 ori mai rapid. Să analizăm cum funcționează indicii de acoperire.
Aplicăm indicatori care acoperă
- Porniți SQL Server Management Studio, deschideți fereastra New Query și modificați contextul bazei de date la Adventure Works.
- Ideea de acoperire a indicilor este că ele conțin toate datele necesare pentru a îndeplini interogările. Dacă ne uităm la prima dintre următoarele interogări care au fost deja utilizate în exemplul anterior, vom vedea că SQL Server are nevoie de coloanele SalesOrderID. CarrierTrackingNumber și ID-ul produsului.
Indice nonclustered NCLIX_OrderDetails_ProductID. pe care l-am creat mai devreme, include coloana ProductID. deoarece este construit pe această coloană, precum și coloana SalesOrderID. Deoarece această coloană este coloana cheie a indexului grupat. Prin urmare, SalesOrderID este un pointer pe care SQL Server îl utilizează într-un index nonclustered. Prin urmare, serverul SQL Server pentru a obține CarrierTrackingNumber. trebuie să returnați rândurile de date executând o căutare (metoda de căutare) numai în indexul grupat. În cea de-a doua interogare, coloana CarrierTrackingNumber nu se află în lista SELECT. Introduceți și urmați instrucțiunile, inclusiv un plan de execuție valabil pentru a vedea diferența. Codul pentru acest exemplu este disponibil în fișierele eșantion sub numele Utilizarea indexes.sql acoperite.
Figura de mai jos arată că serverul SQL Server trebuie să acceseze indexul cluster pentru a rula cea de-a doua interogare, deoarece indexul acoperă cererea dacă coloana CarrierTrackingNumber nu este selectată. Deoarece accesul la indexul cluster pentru fiecare linie este foarte scump, cea de-a doua interogare este de numai 1% din costul total al pachetului. După ce ne uităm la fila Mesaje, vedem asta pentru asta. Pentru a acoperi interogarea, SQL Server trebuie doar să efectueze citiri de 2 pagini (în loc de cele 709 citiri necesare pentru prima interogare).
Sunteți convins că indicele de acoperire poate da un mare câștig în viteza de execuție. Desigur, nu puteți șterge coloane dintr-o interogare dacă acestea sunt necesare ca rezultat. Dar, ca regulă generală, trebuie să recuperați doar coloanele de care aveți cu adevărat nevoie pentru a face indexul de acoperire mai probabil. Nu utilizați asteriscul (*) în instrucțiunea SELECT doar pentru că este mai ușor să scrieți o interogare.
Privind planul de execuție, veți vedea că accesul la indexul cluster nu mai este necesar. Fila mesajului arată că pentru a executa această interogare sunt necesare doar 5 pagini, în timp ce 709 a fost solicitat anterior.
Notă. Coloanele incluse determină supraîncărcarea serverului SQL atunci când datele sunt modificate, deoarece SQL Server trebuie să schimbe fiecare index și deoarece este nevoie de mai mult spațiu de stocare pentru a stoca indexul. Prin urmare, inclusiv coloanele din indexurile noncluste reprezintă o modalitate bună de a îmbunătăți performanța interogării, dar nu ar trebui să creați indici care să includă coloane pentru toate interogările din aplicație. Această funcție ar trebui utilizată numai pentru a accelera executarea unor interogări problematice.
Indicii în coloanele calculate
În tabela dbo.OrderDetails, avem o coloană calculată LineTotal. care reprezintă valoarea LineTotal pentru un șir și se calculează utilizând următoarea formulă: