19.03.2021

SQL Server -də sorğu planlarının təhlili. Önbelleğe alınmış SQL sorğu icra planı uğursuz oldu, ms sql sorğu planı oxundu


Yəqin ki, hər 1C ləqəbi "HANSINDAN daha sürətli, bir əlaqə və ya şərt?" Sualını verdi. və ya, məsələn, "alt sorğu etmək və ya B () operatorunu qoymaq"?

Bundan sonra, 1C ləqəbi foruma gedir və orada ona deyirlər - istək planına baxmaq lazımdır. Baxır və heç nə başa düşmədən, planlar vasitəsilə sorğuların optimallaşdırılması fikrini həmişəlik tərk edir, sadəcə performansı ölçməklə variantları müqayisə etməyə davam edir.

Nəticədə, geliştiricinin maşınında, istək sadəcə uçmağa başlayır və sonra döyüş bazasında, qeydlərin sayının artması ilə hər şey ölür və "1C yavaşlayır" üslubunda şikayətlər başlayır. Tanış bir şəkil, elə deyilmi?

Bu yazıda sizə sorğu planlarının necə oxunacağına dair hərtərəfli təlimat verməyəcəyəm. Ancaq bunun nə olduğunu və onlara hansı tərəfdən yanaşmağınızı açıq şəkildə izah etməyə çalışacağam.

Üstəlik, özümü yaxşı bir sorğu optimallaşdırıcısı hesab etmirəm, buna görə məqalədə faktiki səhvlər çox ehtimal olunur. Yaxşı, onda icazə verin guru şərhlərdə məni düzəltsin. Bu səbəbdən buradayıq və cəmiyyət bir -birimizə kömək etmək üçün, elə deyilmi?

Əgər artıq sorğu planlarını oxumağı bilirsinizsə, məqaləni atlamalısınız. Burada ən sadə və əvvəldən olacaq. Məqalə, bunun nə cür bir heyvanı - sorğu planını hələ başa düşməyən inkişaf etdiricilər üçün nəzərdə tutulmuşdur.

Kompüter necə işləyir

Uzaqdan başlayacam. Əsas odur ki, istifadə etdiyimiz kompüterlər o qədər də ağıllı deyil. Yəqin ki, kompüter elminin ilk dərslərini və ya ali məktəb kurslarını xatırlayırsınız? Orada bir baloncukla serialları sıraladığınızı və ya bir satır satır oxuduğunuzu xatırlayırsınızmı? Beləliklə, müasir əlaqəli DBMS -də kökündən yeni bir şey icad edilməmişdir.

Laboratoriyalarda bir fayldakı sətirləri oxuyursunuz və sonra başqa bir yerə yazırsınızsa, artıq müasir bir DBMS -in necə işlədiyinə dair kobud bir təsəvvürünüz var. Bəli, əlbəttə ki, orada hər şey çox (çox) daha mürəkkəbdir, ancaq Afrikadakı dövrlərdir, disk oxumaq hələ də RAM oxumaqdan daha sürətli olmadı və O (N) alqoritmləri hələ də O (1) alqoritmlərindən daha yavaşdır. artması ilə N.

Təsəvvür edək ki, bir adam sizə gəlir, sadə 1C ləqəbi və deyir: "Bax dostum, bir verilənlər bazası yazmalısan. Budur bir fayl, içərisinə bəzi sətirlər yaz. Sonra oradan oxu". Deyək ki, imtina edə bilməzsən. Bu problemi necə həll edərdiniz?

Bunu Microsoft, Oracle, Postgres və 1C -dən olan uşaqlar həll etdiyi kimi həll edərdinizmi? Proqramlaşdırma dilinizdən istifadə edərək faylı açıb oradakı sətirləri oxuyub ekranda göstərərdiniz. Dünya, yuxarıda təsvir etdiyimdən tamamilə fərqli bir alqoritm yaratmadı.

2 faylınız olduğunu düşünün. Birində qarşı tərəflər, digəri isə qarşı tərəflərin müqavilələri var. INNER JOIN əməliyyatını necə həyata keçirərdiniz? Düzgün irəli, heç bir optimallaşdırma olmadan?

Podratçılar

Müqavilələr

Podratçı ID

Müqavilənin sayı

Sadəlik naminə faylları açmaq və yaddaşa oxumaq nüanslarını buraxaq. Birləşmə əməliyyatlarına diqqət edək. Bunu necə edərdiniz? Bunu belə edərdim:

Hər bir LineContractor üçün Counterparties Dövründən Hər bir LineAqrantdan Müqavilə Dövründən Müqavilənin LineAg anlaşması.ID = StringContractor.ID Sonra OutputConnectionResult (StringContractor, StringAg anlaşma); EndIf; Dövrün sonu; Dövrün sonu;

Misalda f-I PrintConnectionResult, keçilən satırlardan bütün sütunları göstərəcəkdir. Onun kodu burada vacib deyil.

Beləliklə, iki yuvalı döngə görürük. Xarici olaraq bir -bir masa, sonra daxili birində - sadə axtarışla xarici bir açar axtarın. Və birdən -birə, 1C DBMS -dən hər hansı birində BAĞLANTI ilə hər hansı bir sorğunun planını açarsanız, olduqca yüksək bir ehtimalla oradakı "Nested Loops" quruluşunu görəcəksiniz. Bunu potensial düşmənin dilindən bizimkilərə tərcümə etsəniz, "İçəri döngələr" alacaqsınız. Yəni "sorğu planında" DBMS sizə burada "əlaqə" üçün yuxarıda təsvir olunan alqoritmi tətbiq etdiyini izah edir. Təxminən 7 -ci sinif şagirdləri bu alqoritmi yaza bilərlər. Və dünya səviyyəli güclü DBMS-lər bu alqoritmi olduqca sakit istifadə edirlər. Bəzi vəziyyətlərdə - ümumiyyətlə ən yaxşı şeydir.

Və ümumiyyətlə, niyə dərhal "əlaqə" ilə başladım? Güman edək ki, adla bir iş ortağı tapmaq lazımdır. Bu problemi necə həll edərdiniz? Burada podratçılarla bir sənədiniz var. Bir alqoritm yazın. Bunu belə yazacam:

Müqavilə Tərəfindən Hər Bir Podratçı Xətti üçün Əgər Podratçı Xətti.Ad = "İvanov" Sonra Çıxış Nəticəsi (Podratçı Xətti); EndIf; Dövrün sonu;

Yox, yaxşı, ciddi, başqa necə yaza bilərsən? Ancaq mahiyyət etibarilə heç bir şəkildə. Cədvəldəki girişlərin hansı ardıcıllıqla olduğu bilinmirsə, kim nə deyə bilərsə, hamısına yenidən baxmalı olacaqsınız. Sorğu planı dilində buna Tarama deyilir. Skan edilir. Tam məlumat görünüşü və başqa heç nə yoxdur.

İndekslər

Cədvəldəki məlumatların axtarışını necə sürətləndirə bilərik? Həqiqət budur ki, hər şeyi hər dəfə nəzərdən keçirmək bir növ pislikdir.

Bir klinikada və ya kitabxanada bir fayl kabinetini xatırlayaq. Müştərinin soyadı ilə orada axtarış necə aparılır? Taxta şkaflarda A -dan Z -yə qədər hərfləri olan səliqəli kartlar var və xəstə "Pupkin" "P" kartlı bir kabinetdədir. Ardıcıl olaraq bütün digər hərfləri nəzərdən keçirməyə ehtiyac yoxdur. Cədvəlimizdəki məlumatları sıralasaq və "P" hərfi olan qeydlərin harada (hansı sətir nömrələri altında) olduğunu bilsək, reyestrdən xalanın performansına əhəmiyyətli dərəcədə yaxınlaşacağıq. Və bu kobud gücdən daha yaxşıdır, elə deyilmi?

Beləliklə, "İndeks" sözü bu kontekstdə (yenə potensial düşmənin dilindən tərcümə edilmiş) "İçindəkilər" deməkdir. Bir kitabda bir fəsli tez bir zamanda tapmaq üçün məzmun cədvəlinə gedirsən, orada fəslin adını tapırsan, sonra səhifə nömrəsinə baxırsan və birbaşa bu səhifəyə gedirsən.

Verilənlər bazasında cədvəldə bir qeyd tapması lazım olduqda, məzmun cədvəlinə keçir, qarşı tərəfin adına baxır, altında olduğu qeydin sayına baxır və sənədin tələb olunan sahəsinə gedir. bu qeyddən dərhal sonra məlumat faylı.

Kod şəklində, belə bir şey görünə bilər:

İndeks = Yeni Uyğunluq; // blah blah RecordNumber = İndeks ["İvanov"] DisplayResult (Podratçılar Cədvəli [RecordNumber]);

Möcüzələrin olmadığı məlumdur, buna görə "İndeks" matçının xatirəsi, eləcə də matçın özündə axtarış pulsuz əməliyyatlar deyil. Ancaq bütün məlumatları təkrarlamaqdan daha ucuzdur. Bəli, ana məlumatları əlavə etdiyiniz və ya dəyişdirdiyiniz zaman bu Uyğunluq daim yenilənməlidir.

İndi düşünək, bu indeksi necə həyata keçirərdiniz? Qeydləri məlumat faylında dərhal sıralanmış formada saxlamaq mümkündür. Və hər şey yaxşı olardı, amma birincisi, hər dəfə fərqli sahələrdə axtarmalısan, ikincisi, istifadəçi artıq A -dan Z -yə doldurulmuş cədvələ M hərfi ilə bir qeyd daxil etmək istəyirsə? Amma o, sizi əmin edirəm.

Faylın ümumiyyətlə necə yazıldığını xatırlayaq.

Fseek (fayl, mövqe); // yazmaq istədiyiniz ünvana gedin (fayl, dataArray, dataLength); // dataArray -dən dataLength baytlarını yazın

Vəzifə ünvanı faylın ortasında bir yerə işarə edirsə və bu yerdə məlumatlar varsa, yeniləri ilə yazılır. Bir faylın ortasına bir şey (və yaddaşdakı bir sıra) daxil etməlisinizsə, yerdən sonra hər şeyi açıq şəkildə "hərəkət etdirməlisiniz" və yalnız sonra yeni məlumatlar yazmalısınız. Təsəvvür etdiyiniz kimi, məlumatların "dəyişməsi" yenə dövrlər və giriş / çıxış əməliyyatlarıdır. Yəni o qədər də sürətli deyil. Kompüterdə heç bir şey "öz -özünə" olmur. Hamısı əmrlə.

İndeksə qayıdaq. İstifadəçi ortasına bir şey daxil etmək istəyir. İstəsəniz də, istəməsəniz də, məlumatları bir siyahıda bir -biri ilə əlaqəli "səhifələrdə" saxlamaqla hərəkət etməli olacaqsınız. Fiziki olaraq sona və ya boş bir yerə yazın, amma sanki masanın ortasındadır. Və sonra məzmun cədvəlindəki rekord nömrələri yeniləyin. İndi dəyişdilər və indeks səhv yeri göstərir. Yəqin eşitmişdiniz ki, verilənlər bazasındakı indekslər axtarışları sürətləndirir, lakin əlavə və silmələri ləngidir. İndi bunun niyə belə olduğunu bilirsiniz.

Yaxşı, fərqli sahələrdə axtarış problemini hələ həll etməmişik. Verilənləri fərqli bir qaydada bir faylda saxlaya bilmərik. Bir istifadəçi adı ilə, digəri isə tarixə görə. Və eyni zamanda. Bu problemi necə həll edərdiniz? Fikrimcə, həll göz qabağındadır - ayrı -ayrı məlumatları və ayrıca məzmun cədvəllərini lazımi sahələrə görə sıralamalısınız. Bunlar. verilənlər bazası lazım olduqda verilənlər bazasındadır, ancaq yanında qeydlərin ada görə sıralandığı bir fayl yaradacağıq. Bu, "Ad" sahəsindəki indeks olacaq. Və yanında başqa bir oxşar fayl olacaq, ancaq "Tarix" sahəsinə görə sıralanmışdır. Məkana qənaət etmək üçün əsas cədvəlin bütün sütunlarını indekslərdə saxlamayacağıq, ancaq sıralamanın aparıldığı sütunları (burada tez axtarış etmək üçün, qeyd nömrəsini tapıb dərhal ona keçərək qalan məlumatları oxumaq üçün) ).

Yetkin DBMS yazan uşaqlar da bundan yaxşı bir şey tapmadılar. Verilənlər bazasındakı indekslər bu şəkildə düzülmüşdür. Cədvəldəki bütün məlumatlar ayrı bir varlıqda yan -yana sıralanır. Əslində bir indeks başqa bir cədvəldir. Və məntiqi olan əsas masanın ölçüsü ilə nisbətdə yer tutur. Bəli, orada balanslaşdırılmış ağaclar və bunların hamısı kimi fərqli fəndlər var, amma mənası çox dəyişmir.

Yeri gəlmişkən, məlumatı dərhal sifariş verilmiş ana cədvələ yazsanız, ayrıca saxlanılan bir indeks hazırlamalı və məlumat cədvəlinin özünü indeks hesab etməlisiniz. Əla, elə deyilmi? Belə bir indeks "qruplaşdırılmış" adlanır. Cədvəldəki qeydlərin sıralandığı sahənin monoton şəkildə böyüməyə çalışması məntiqlidir. Ortadakı əlavəni xatırlayırsınız, elə deyilmi?

Sorgu icrasının planlaşdırılması

Təsəvvür edin ki, beş milyon qeydli bir masanız var. Və onun indeksi var. "Salam" sözü olan girişi tez tapmalıyıq. Eyni cədvəliniz olduğunu, ancaq üç qeydiniz olduğunu təsəvvür edin. Həm də "Salam" tapmalısınız. Hansı axtarış metodunu seçməlisiniz? İndeks faylını açın, ikili axtarışla işləyin, istədiyiniz qeyd nömrəsini tapın, əsas masa faylını açın, nömrəsinə görə qeydə gedin, oxuyun? Yoxsa hər bir qeyd üçün bir şərt yoxlayaraq birdən üçə qədər bir döngə başlasın? Müasir kompüter birdən üçə qədər olan dövrləri olduqca dəhşətli dərəcədə tez yerinə yetirir.

Bir qərar qəbul etmək üçün sorğu planlayıcısı bunun nə ilə məşğul olduğunu anlamalıdır. Statistika kimi bir şeylə işləyir. Statistikaya cədvəllər üzrə qeydlərin sayı, məlumatların sütunlara görə paylanması, seçicilik və s. Daxildir. Bütün bunlar planlayana hansı məlumat toplama üsulunun daha sürətli olacağına dair göstərişlərdir. Mümkün olan ən sürətli deyil, ən azından bəzi ehtimallarla kifayət qədər sürətli. Və planlayıcının qərar vermək üçün məhdud vaxtı var. məlumatları tez əldə etmək istəyirik və orada özü üçün planlaşdırarkən gözləmirik.

Burada əvvəlcə dissertasiyamı müdafiə etmədən planlayıcılığa başlamazdım. Orada necə işləyir və bunu necə dözümlü şəkildə həyata keçirir - bilmirəm. Buna görə də, DBMS sənədləri ilə məhdudlaşacağıq. Buradan belə çıxır ki, planlaşdırıcı statistikaya əsaslanaraq sorğunun addım-addım yerinə yetirilməsi üçün bir neçə mümkün variant qurur və sonra ən uyğununu seçir. Məsələn, rast gəlinən ilk. Həm də evristikdir, elə deyilmi?

"Əvvəlcə nə etməliyəm" - planlaşdırıcı düşünür: "Bütün A cədvəlini keçin, qeydləri şərtlərə görə seçin və sonra B cədvəlinə daxil edilmiş döngələrlə qoşulun və ya B cədvəlinin bütün uyğun qeydlərini indekslə tapın və yalnız bundan sonra gedin. A "masası vasitəsilə? Adımların hər birinin müəyyən bir çəkisi və ya dəyəri var. Xərc nə qədər yüksək olsa, onu icra etmək bir o qədər çətindir. Sorğu planı, DBMS mühərrikinin sorğu nəticələrini toplamaq üçün atdığı hər bir addımın dəyərini həmişə siyahıya alır.

Operator cihazını planlaşdırın

Sorğu planının hər bir addımı, girişi bir qeydlər, çıxışı isə başqa bir obyekt şəklində həyata keçirilir. Kod daxil etsəniz, sorğu planı operatorunun bir üsulla mücərrəd bir interfeysin həyata keçirildiyi ortaya çıxır:

IQueryOperator interfeysi (DataRow GetNextRow ();)

burada yazılanları anlamayanlar üçün izah edim. Hər bir sorğu planı ifadəsində GiveNextRecord metodu var. DBMS mühərriki bu üsul üçün operatoru cəlb edir və hər belə bir çəkmə ilə nəticələnən rekordu sorğu nəticəsinə əlavə edir. Məsələn, bir qeyd süzgəc operatoru girişdə bütün cədvələ və yalnız çıxışdakı şərti təmin edənlərə malikdir. Bundan əlavə, bu operatorun çıxışı operatora verilir, məsələn, İLK 100, sonra da toplama operatoruna (SUM və ya QUANTITY), eyni şəkildə içəridə bütün emalları əhatə edir və nəticə ilə bir qeyd çıxarır. .

Şematik olaraq belə görünür:

AllData -> Süzün (Ad = "Petrov") -> Üst (100) -> Toplama (QUANTITY)

Sorğu planını açdığınız zaman oxlarla bağlanmış kublar görəcəksiniz. Kublar operatordur. Oklar - məlumat axınının istiqaməti. Məlumatlar oxlar boyunca bir operatordan digərinə keçir və sonunda sorğu nəticəsinə birləşir.

Hər bir operatorun müəyyən parametrləri var: işlənmiş qeydlərin sayı, dəyəri, I / O əməliyyatlarının sayı, önbelleklərin istifadəsi və s. Bütün bunlar sorğunun icrasının səmərəliliyini qiymətləndirməyə imkan verir. Milyon qeyddən keçən və iki çıxışı olan bir masanı taramaq çox yaxşı bir sorğu planı deyil. Ancaq planlaşdırıcı daha yaxşı bir şey tapmadı. Axtarmaq üçün indeksi yox idi. Və ya bəlkə də statistika yalan danışaraq cədvəldə üç qeyd olduğunu söylədi, amma əslində bir milyon ədəd yazmağı bacardılar, amma statistika yenilənmədi. Bunların hamısı tələbi araşdıran mühəndis tərəfindən nəzərdən keçirilir.

Bir sorğu planı, addım-addım sorğu ayıklayıcıdır. Nəticəni qaytarmaq üçün DBMS -in tam olaraq nəyi, hansı alqoritmi (sözün həqiqi mənasında) addım -addım görürsünüz. Alqoritmlərin özlərini gördünüz - çox mürəkkəbdir, çünki döngələr və şərtlər var. Bəzən bir neçə dövrə belə içəri girir, bu dəhşətdir. Hər bir operatorda hansı proseslərin baş verdiyini anlamaq vacibdir. İcra zamanı qeydlər massivinə hansı alqoritm tətbiq edilib və nə qədər işləyib.

Növbəti məqalədə sorğu planlarında olan xüsusi operatorları və onların daxili quruluşunu nəzərdən keçirməyi planlaşdırıram. Sona qədər oxuduğunuz üçün təşəkkürlər!

SQL Server.

Sorğu planları

SQL Server bir sorğu işlədərkən ilk növbədə ən yaxşı icra üsulunu təyin etməlidir. Bunu etmək üçün məlumatlara necə və hansı qaydada daxil olmağı və onları birləşdirməyi, hesablamaları və yığımları necə və nə vaxt yerinə yetirməyi və s. Hesablamaq lazımdır. Query Optimizer adlı bir alt sistem ( Sorğu optimallaşdırıcısı). Sorğu optimallaşdırıcısı bir neçə mümkün sorğu icra planını hesablamaq üçün məlumatların paylanması, verilənlər bazasındakı obyektlərlə əlaqəli metadata, indeks məlumatları və digər amillərdən istifadə edir. Bu planların hər biri üçün Sorğu optimallaşdırıcısı bu məlumatların statistikasına əsaslanaraq xərcini öz üzərinə götürür və icrası üçün minimum resursları olan bir plan seçir. Əlbəttə ki, SQL Server hər bir sorğu üçün bütün mümkün planları hesablamır, çünki bəzi sorğular üçün hesablamanın özü icra etmək üçün ən səmərəli plandan daha uzun çəkə bilər. Nəticə etibarilə, SQL Server, mümkün olan ən aşağı qiymətə yaxın, uyğun bir xərclə bir icra planı tapmaq üçün inkişaf etmiş alqoritmlərdən istifadə edir. İcra planı yaradıldıqdan sonra, tampon önbelleğinde saxlanılır (SQL Server virtual yaddaşının çox hissəsini ayırır). Sonra plan bu şəkildə icra olunur Sorğu optimallaşdırıcısı verilənlər bazası mühərrikinə hesabat verir.

Qeyd... Tampon önbelleğindeki icra planları eyni və ya bənzər bir sorğu icra edilərkən yenidən istifadə edilə bilər. Nəticədə, icra planları mümkün qədər uzun müddət yaddaşda saxlanılır. İcra planlarının önbelleğe alınması haqqında daha çox məlumat üçün, http: / / www.microsoft.com/ technet / prodtechnol / sql / 2005 / recomp ünvanındakı "SQL Server 2005 -də Toplu Kompilyasiya, Yenidən Kompilyasiya və Önbelleğe Alma Məsələləri" başlıqlı ağ kağıza baxın. mspx.

Can Sorğu Optimizatoru ( Sorğu optimallaşdırıcısı) müəyyən bir sorğu üçün səmərəli bir plan hazırlamaq aşağıdakı aspektlərdən asılıdır:

  • İndekslər... Bir kitabdakı məzmun cədvəli kimi, verilənlər bazası indeksi cədvəldəki xüsusi satırları tez bir zamanda tapmağa imkan verir. Cədvəldə birdən çox indeks ola bilər. Cədvəldə indekslərin olması səbəbindən Sorğu optimallaşdırıcısı SQL Server istifadə etmək üçün uyğun indeksi seçərək məlumat girişini optimallaşdıra bilər. İndeks yoxdursa, Query Optimizer -in ehtiyac duyduğu satırları tapmaq üçün cədvəldəki bütün məlumatları taramaq üçün yalnız bir seçimi var. Bu fəslin qalan hissəsi indekslərin necə işlədiyini və necə dizayn ediləcəyini və dizayn edildiyini göstərir.
  • Məlumat paylama statistikası: SQL Server məlumatların paylanması ilə bağlı statistikanı saxlayır. Bu statistika yoxdursa və ya köhnəlmişsə, Sorğu optimallaşdırıcısı sorğu üçün səmərəli icra planını hesablaya bilməyəcək. Əksər hallarda statistika avtomatik olaraq yaradılır və yenilənir. Bu fəslin qalan hissəsi statistikanın necə yaradıldığını və statistikanın necə idarə oluna biləcəyini izah edir.

Gördüyünüz kimi, bir sorğu icra planı yaratmaq SQL Server performansı üçün vacib bir xüsusiyyətdir, çünki sorğu planının səmərəliliyi onun icra müddətinin milisaniyə, saniyə və ya hətta dəqiqə ilə ölçülüb -ölçülmədiyini müəyyən edir. Yavaş icra sürətini göstərən sorğular üçün icra planları, indeks olub olmadığını, statistikanın köhnəlmiş olub olmadığını və ya SQL Serverin sadəcə az işləyən bir plan seçdiyini (bu çox tez -tez baş vermir) müəyyən etmək üçün təhlil edilə bilər.

Qeyd... Əlbəttə ki, səmərəsiz icra olunan bir sorğunun yaxşı bir plana uyğun olması mümkündür. Bu hallarda, bu məsələ deyil sorğu optimallaşdırması... Çox güman ki, problem tamamilə fərqli bir şeydədir, məsələn, istək layihəsində, giriş ziddiyyəti məlumat, I / O, yaddaş, CPU istifadəsi, şəbəkə mənbələri və daha çoxu. Bu məsələlər haqqında daha çox məlumat üçün aşağıdakı linkdə mövcud olan SQL Server 2005 -də Performans Problemlərinin Giderme kitabına baxın: SQL Server 2005). http://www.microsoft.com/ technet / prodtechnol / sql / 2005 / tsprfprb.mspx.

Sorğunun icra planları ilə tanış olmaq

  1. Başlat menyusundan Bütün Proqramları seçin. Microsoft SQL Server 2005, SQL Server Management Studio (Bütün Proqramlar, Microsoft SQL Server 2005, SQL Server Management Studio). Yeni bir sorğu pəncərəsi açmaq və Available Databases açılan siyahısından seçərək icra kontekstini Adventure Works verilənlər bazasına dəyişdirmək üçün Yeni Sorğu düyməsini basın.
  2. Aşağıdakı SELECT ifadəsini icra edin. Bu nümunənin kodu, Viewing adı altında nümunə fayllarda mövcuddur Sorgu Planları .sql.
  3. Bu sorğunun icra planını göstərmək üçün Ctrl + L düymələrini basın və ya Sorgu menyusundan Tahmini İcra Planını Göstər seçin. İcra planı aşağıdakı şəkildə göstərilmişdir.

    Nəzərdə tutulan sorğu planı yaradılarkən sorğu əslində icra edilmir. Yalnız Query Optimizer tərəfindən optimallaşdırılmışdır. Query Optimizer -in bu xüsusiyyəti, uzun dövr müddəti olan sorğularla məşğul olmağınız lazım olduğu üçün bir üstünlükdür, çünki sorğunun icra planını görmək üçün sorğunu icra etməyinizə ehtiyac yoxdur. Sorğu icra planının qrafik təsviri sağdan sola və yuxarıdan aşağıya oxunur. Plandakı hər bir simvol bir operatoru təmsil edir və bu operatorlar arasında dəyişən məlumatlar oxlarla göstərilir. Okların qalınlığı operatorlar arasında ötürülən məlumatların miqdarına uyğundur. Detallara girməyəcəyik və hər bir operatorun mənasını izah etməyəcəyik; yalnız bu sorğu icra planında göstərilənlər haqqında danışacağıq.

    • SQL Server, Kümelenmiş İndeks Tarama əməliyyatından istifadə edərək məlumatlara daxil olur. qruplaşdırılmış indeks). Bu tarama əsl məlumat əldə etmə əməliyyatıdır və aşağıda ətraflı müzakirə olunur.
    • Məlumatlar SİPARİŞ BY maddəsinə əsasən məlumatları sıralayan Sort operatoruna axır.
    • Məlumatlar müştəriyə göndərilir.

    İndeksləri və qoşulmaları araşdırarkən SQL Server -in istifadə etdiyi ən vacib operatorlara baxacağıq. Bəyanatların tam siyahısı üçün "Qrafik İcra Planı Nişanları" mövzusunda SQL Server 2005 Books Online -a baxın.

    Hər bir operatorun simvolu altında olan Faiz Qiyməti, qrafik diaqramda təqdim olunan sorğunun ümumi dəyərinin faizini göstərir. Bu rəqəm, hansı əməliyyatın icra zamanı ən çox qaynaq istifadə etdiyini anlamanıza kömək edəcək. Bizim vəziyyətimizdə ən bahalı əməliyyat Kümelenmiş İndeks Taramasıdır. Bu məlumatlar "Proqnozlar" bölməsindədir. Həm də satırların təxmini dəyərini və təxmin edilən sayını, eləcə də satır ölçüsünü göstərir. Satır sayıları SQL -in statistikasına əsasən hesablanır. Bu cədvəl üçün server mağazaları, xərc dəyərləri statistikaya və istinad sistemindəki dəyərlərə əsaslanaraq hesablanır.Bu səbəbdən xərc dəyərləri kompüterdə bir sorğunun nə qədər işləyəcəyini hesablamaq üçün istifadə edilməməlidir. daha ucuz və ya daha bahalı əməliyyat.

  4. Bu operator məlumatlarını SQL Server Management Studio -dakı Xüsusiyyətlər pəncərəsində də görə bilərsiniz. Xüsusiyyətlər pəncərəsini açmaq üçün operator simgesini sağ vurun və kontekst menyusundan Xüsusiyyətlər seçin.
  5. Sorğu planları da saxlanıla bilər. Sorğu planını saxlamaq üçün plan bölməsinə sağ vurun və kontekst menyusundan İcra Planını Kimi Saxla seçin. Plan .sqlplan uzantısı ilə XML formatında saxlanılır. SQL Server Management Studio vasitəsilə açıla bilər. Fayl menyusundan Aç, Fayl seçərək.
  6. İndiyə qədər gördükləriniz sorğunun təxmini icra planıdır, ancaq faktiki icra planını da görə bilərsiniz. Həqiqi icra planı, təxmin edilən icra planı ilə eynidir, eyni zamanda sətirlərin sayı, geri çəkmə sayı və s. Üçün faktiki (təxmin edilməmiş) dəyərləri də ehtiva edir. Faktiki icra planını sorğuya daxil etmək üçün, (Ctrl + M) düyməsini basın və ya Sual menyusundan Həqiqi İcra Planını Daxil et əmrini seçin. Sonra F5 düyməsini basın və sorğunu icra edin. Sorğu nəticələri hər zamanki kimi göstərilir, ancaq İcra Planı sekmesinde göstərilən icra planını da görəcəksiniz.

6 cavab

Vəziyyətinizdən asılı olaraq istifadə etdiyiniz bir icra planı əldə etməyin bir neçə yolu var. Planı əldə etmək üçün adətən SQL Server Management Studio -dan istifadə edə bilərsiniz, lakin nədənsə sorğunuzu SQL Server Management Studio -da işlədə bilmirsinizsə, planı SQL Server Profiler vasitəsilə və ya planı yoxlayaraq əldə etməyiniz faydalı ola bilər. gizli yer.

Metod 1 - SQL Server Management Studio -dan istifadə

SQL Server, bir icra planı toplamağı asanlaşdıran bəzi səliqəli xüsusiyyətlərə malikdir, yalnız Aktual İcra Planını Daxil et (Sorgu menyusunda tapılır) menyu maddəsinin işarələndiyinə və hər zamanki kimi sizinki kimi işləyəcəyinə əmin olun.

Saxlanılan bir prosedurda ifadələr üçün icra planını əldə etməyə çalışırsınızsa, saxlanılan proseduru yerinə yetirməlisiniz, məsələn:

Exec p_Məsələn 42

Sorğunuz tamamlandıqda, nəticələr bölməsində görünən əlavə İcra Planı sekmesini görəcəksiniz. Bir çox iddia irəli sürsəniz, bu sekmədə bir çox planın göstərildiyini görə bilərsiniz.

Burada SQL Server Management Studio-da icra planını yoxlaya bilərsiniz və ya planı sağ tıklayaraq "İcra Planını Kimi Saxla ..." seçərək planı XML formatında bir faylda qeyd edə bilərsiniz.

Metod 2 - SHOWPLAN seçimlərindən istifadə

Bu üsul 1 -ci üsula çox oxşardır (əslində SQL Server Management Studio daxili olaraq nə edir), lakin tamlığı üçün daxil etmişəm və ya SQL Server Management Studio yoxdursa.

Qaç bir aşağıdakı operatorlar. Operator paketdəki yeganə operator olmalıdır, yəni. Başqa bir ifadəni eyni anda icra edə bilməzsiniz:

SHOWPLAN_TEXT SET ÜZRƏ AYAR SHOWPLAN_XL SET STATISTICS SET STATISTICS XML ON PROFİLİ - İstifadə etmək üçün tövsiyə olunan seçimdir

Bunlar əlaqə parametrləridir, buna görə hər əlaqə üçün yalnız bu dəfə işləməlisiniz. Bundan sonra başladılan bütün bəyanatlar izləniləcək əlavə nəticələr toplusuİcra planınızı istədiyiniz formatda ehtiva edin - planı görmək üçün sorğunuzu hər zamanki kimi yerinə yetirin.

İşiniz bitdikdən sonra bu ifadəni aşağıdakı ifadə ilə deaktiv edə bilərsiniz:

SET<

İcra planı formatlarının müqayisəsi

Güclü bir seçiminiz varsa, STATISTICS XML seçimindən istifadə etməyi məsləhət görürəm. Bu seçim, SQL Server Management Studio -da Faktiki İcra Planını Daxil et seçiminə bərabərdir və ən böyük məlumatı ən əlverişli formatda təqdim edir.

  • SHOWPLAN_TEXT - Bir sorğu icra etmədən mətnə ​​əsaslanan təxmini icra planını göstərir
  • SHOWPLAN_ALL - Sorğunu yerinə yetirmədən bir xərc smetası ilə təxmin edilən mətn əsaslı icra planını göstərir
  • SHOWPLAN_XML - XML ​​əsaslı bir icra planını, sorğunu yerinə yetirmədən xərclər smetası ilə göstərir. Bu, SQL Server Management Studio -da "Təxmini icra planını göstər ..." seçiminə bərabərdir.
  • STATİSTİKA PROFİLİ - Sorğunu yerinə yetirir və faktiki mətn əsaslı icra planını göstərir.
  • STATISTICS XML - Sorğunu yerinə yetirir və faktiki XML əsaslı icra planını göstərir. Bu, SQL Server Management Studio -da "Həqiqi İcra Planını Daxil et" seçiminə bərabərdir.

Metod 3 - SQL Server Profilerindən istifadə

Sorğunu birbaşa işlədə bilmirsinizsə (və ya sorğunuz birbaşa işlədikdə yavaş işləmir - unutmayın ki, sorğu planının zəif yerinə yetirilməsini istəyirik), onda SQL Server Profiler izini istifadə edərək planı çəkə bilərsiniz. Fikir, Showplan hadisələrindən birini tutan bir iz işləyərkən sorğunuzu yerinə yetirməkdir.

Yükdən asılı olaraq, siz edə bilərsən bu üsulu istehsal mühitində istifadə edin, ancaq diqqətli olmalısınız. SQL Serverin profilləşdirmə mexanizmləri verilənlər bazasına təsirini minimuma endirmək üçün hazırlanmışdır, lakin bu heç bir performans təsirinin olmayacağı anlamına gəlmir. Veritabanınız çox istifadə olunursa, marşrutunuzu süzmək və düzgün planı müəyyənləşdirməkdə də çətinlik çəkə bilərsiniz. Bunu qiymətli verilənlər bazasında etdiyiniz üçün xoşbəxt olduqlarından əmin olmaq üçün açıq şəkildə DBA -ya müraciət etməlisiniz!

  • SQL Server Profiler proqramını açın və iz yazmaq istədiyiniz verilənlər bazasını birləşdirən yeni bir iz yaradın.
  • Tədbir Seçimi sekmesinde, Bütün Hadisələri Göstər onay kutusunu yoxlayın, Performans xəttini → XML Göstər Planını yoxlayın və izləməyə başlayın.
  • İz işləyərkən, yavaş sorğunun işə salınması üçün nə etmək lazımdırsa edin.
  • Sorğunun tamamlanmasını və izin dayanmasını gözləyin.
  • İzi saxlamaq üçün, SQL Server profilindəki xml planına sağ vurun və Tədbir Məlumatlarını Al ... seçin və planı XML formatında bir faylda qeyd edin.

Aldığınız plan, SQL Server Management Studio -da "Həqiqi İcra Planını Daxil et" seçiminə bərabərdir.

Metod 4 - İstək önbelleğini yoxlayın

Sorğunuzu birbaşa işlədə bilmirsinizsə və profiler izini də ala bilmirsinizsə, hələ də SQL sorğu planı önbelleğini yoxlayaraq təxmin edilən planı əldə edə bilərsiniz.

SQL Server DMV -lərini soruşaraq plan önbelleğini yoxlayırıq. Aşağıda, SQL mətni ilə birlikdə bütün önbelleğe alınmış sorğu planlarını (xml olaraq) siyahıya alacaq əsas bir sorğu var. Əksər verilənlər bazalarında, nəticələri maraqlandığınız planlara süzmək üçün əlavə filtr şərtləri əlavə etməlisiniz.

UseCounts, Cacheobjtype, Objtype, TEXT, sorğu_planını sys.dm_exec_cached_plans -dan SEÇİN CROSS APPLY sys.dm_exec_sql_text (plan_handle) CROSS APPLY sys.dm_exec_query_plan (plan_handle)

Planı yeni bir pəncərədə açmaq üçün bu sorğunu yerinə yetirin və XML planına vurun - planı XML formatında bir faylda saxlamaq üçün sağ vurun və "İcra Planını Kimi Saxla ..." seçin.

Qeydlər:

Bir çox amil (cədvəl və indeks sxemindən saxlanılan məlumatlara və cədvəl statistikasına qədər) olduğundan, etməlisiniz həmişə icra planını maraqlandığınız verilənlər bazasından almağa çalışın (adətən bir performans problemi yaşayan).

Şifrəli saxlanılan prosedurlar üçün bir icra planı çəkə bilməzsiniz.

"faktiki" və "təxmin edilən" icra planları

Faktiki icra planı, SQL Serverin həqiqətən sorğunu icra etdiyi yerdir, təxmin edilən SQL Server icra planı sorğunu icra etmədən edə biləcəyi iş üzərində işləyir. Məntiqi olaraq ekvivalent olsa da, faktiki icra planı daha faydalıdır, çünki sorğu icra edildikdə əslində baş verənlər haqqında əlavə məlumat və statistika ehtiva edir. SQL Server qiymətləndirmələri deaktiv edildikdə (məsələn, statistika köhnə olduqda) problemlərin diaqnozu qoyularkən bu vacibdir.

Sorğu icra planını necə şərh etmək olar?

Pulsuz bir kitab üçün kifayət qədər dəyərli bir mövzudur.

Bəzən yerləşdirilən hərtərəfli cavaba əlavə olaraq, məlumat çıxarmaq üçün proqram planına daxil olmaq faydalıdır. Bunun üçün nümunə kod aşağıda verilmişdir.

@TraceID INT EXEC StartCapture @@ SPID, @TraceID ÇIXIŞ EXEC sp_help "sys.objects" / * BİLDİRİN<-- Call your stored proc of interest here.*/ EXEC StopCapture @TraceID

Sorğu icra planlarını əldə etmək və dərindən təhlil etmək üçün ən çox sevdiyim vasitədir SQL Nəzarət Planı Tədqiqatçısı... İcra planlarının ətraflı təhlili və görselleştirilmesi üçün SSMS -dən daha rahat, rahat və tamamlıdır.

Alətin hansı funksiyaları təklif etdiyini başa düşmək üçün nümunə bir ekran:

Bu alətdə mövcud olan fikirlərdən yalnız biridir. Tətbiq pəncərəsinin altındakı müxtəlif növ icra planları və faydalı əlavə məlumatlar əldə etməyə imkan verən nişanlar dəstinə diqqət yetirin.

Ayrıca, pulsuz versiyasında gündəlik istifadəsinə mane olan və ya sonunda Pro versiyasını almağa məcbur edən heç bir məhdudiyyət görmədim. Beləliklə, pulsuz versiyaya yapışmağı üstün tutursanız, heç bir şey etməyiniz qadağan edilmir.

Əvvəlki cavablarda təsvir olunan üsullarla yanaşı, sərbəst iş planı görüntüleyicisindən və ApexSQL Plan sorğu optimallaşdırma vasitəsindən də istifadə edə bilərsiniz (bu yaxınlarda rastlaşdım).

ApexSQL planını SQL Server Management Studio -da quraşdıra və inteqrasiya edə bilərsiniz, beləliklə icra planlarına birbaşa SSMS -dən baxmaq olar.

ApexSQL Planında Proqnozlaşdırılan İcra Planlarına baxmaq

  • Düyməni basın Yeni sorğu SSMS -də sorğu mətnini sorğu mətn qutusuna yapışdırın. Sağ vurun və kontekst menyusundan Nümunə İcra Planını Göstər seçin.

  1. İcra Planı Qrafiki, Nəticələr bölməsində İcra Planlaması sekmesini göstərir. Sonra icra planını sağ vurun və kontekst menyusundan "ApexSQL Planında Aç" seçin.

  1. Təxmini icra planı ApexSQL Planında açılacaq və sorğuları optimallaşdırmaq üçün təhlil edilə bilər.

ApexSQL Planında Həqiqi İcra Planlarına baxmaq

Sorğunuz üçün həqiqi icra planını görmək üçün əvvəllər qeyd olunan ikinci addıma keçin, lakin indi, təxmin edilən plan görünən kimi, ApexSQL Planındakı əsas lent çubuğundakı Aktual düyməsini basın.

Həqiqi düyməni basmaq, digər icra planı məlumatları ilə birlikdə xərc parametrlərinin ətraflı bir görünüşü ilə faktiki icra planını göstərir.

İcra planlarına baxmaqla bağlı daha çox məlumatı bu linkdən əldə edə bilərsiniz.

Sorğu planları, genişləndirilmiş hadisələr sessiyasından query_post_execution_showplan hadisəsi vasitəsilə əldə edilə bilər. Budur XEvent sessiyasına bir nümunə:

/ * "Sorğu Ətraflı İzləmə" şablonu vasitəsi ilə yaradılmışdır. * / SERVERDƏ OLAY ETKİNLİK ETKİNLİĞİ OLUŞTURMA SESYONU yaradın sqlserver.query_post_execution_showplan (ACTION (package0.event_sequence, sqlserver.plan_handle, sqlserver.query_hash, sqlserver.query_plan_hash, sqlserver.sver_id, or any of following) hadisələr) istədiyiniz kimi. * / ETKİNLİK ƏLAVƏ ET )) VƏ. (., (0))))), ƏLAVƏ ET sqlserver.module_end (SET collect_statement = (1) ACTION (package0.event_sequence, sqlserver.client_app_name, sqlserver.database_id, sqlserver. Plan_handle, sqlserver.query_hash) query_plan_hash, sqlserver.session_id, sqlserver.sql_text, sqlserver.tsql_frame, sqlserver.tsql_stack) WHERE (. (., (4)) AND. (., AD EVDENT))) sqlserver.rpc_completed (ACTION (sql) client_app_name, sqlserver.database_id, sqlserver.plan_handle, sqlserver.query_hash, sqlserver.query_plan_hash, sqlserver.session_id, sqlserver.sql., (4)) VƏ (., (0))), ADD_ EVENT sql collect_object_name = (1) ACTION (package0.event_sequence, sqlserver.client_app_name, sqlserver.database_id, sqlserver.plan_handle, sqlserver.query_hash, sqlserver.query_plan_hash, sqlserver.session_id, sqlserver.sql_trl (sql) tslserver_frame) (sqlserver.tslserver_frame) (sqlserver.tslserver_frame) (sqlserver.tslserver_frame) (sqlserver.tslserver.frame)) VƏ. .client_app_name, sqlserver.database_id, sqlserver.plan_handle, sqlserver.query_hash, sqlserver.query_plan_planver .sql_text, sqlserver.tsql_frame, sqlserver.tsql_stack) WHERE (.) ()) (4) (0) , ƏLAVƏ ET (.) (., (4)) ()) TARGET paketi əlavə et 0.ring_buffer İLƏ (MAX_MEMORY = 4096 KB, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS, MAX_DISPATCH_LATENCY = 30 SECON) DS, MAX_EVENT_SIZE = 0 KB, MEMORY_PARTITION_MODE = YOX, TRACK_CAUSALITY = ON, STARTUP_STATE = OFF)

Bir sessiya yaratdıqdan sonra (SSMS -də) Object Explorer -ə gedin və İdarə et | Genişləndirilmiş Tədbirlər | Sessiyalar. GetExecutionPlan sessiyasına sağ vurun və başlayın. Sağ vurun və "Canlı Veriləri İzlə" seçin.

Sonra yeni bir sorğu pəncərəsi açın və bir və ya daha çox sorğu işlədin. Budur AdventureWorks üçün:

AdventureWorks istifadə edin; Məhsul Adı, Qeyri -DiskontSatışları = (OrderQty * UnitPrice), Endirimlər = ((OrderQty * UnitPrice) * UnitPriceDiscount) -dan SEÇİN. GET

Bir -iki dəqiqədən sonra "GetExecutionPlan: Canlı Məlumatlar" sekmesinde bəzi nəticələr görəcəksiniz. Şəbəkədəki query_post_execution_showplan hadisələrindən birini seçin və sonra ızgaranın altındakı Sorgu Planı sekmesini basın. Bu belə bir şeyə bənzəməlidir:

EDIT: XEvent kodu və ekran görüntüsü SQL / SSMS 2012 w / SP2 -dən yaradılmışdır. SQL 2008 / R2 istifadə edirsinizsə, onu işlətmək üçün skripti fərdiləşdirə bilərsiniz. Ancaq bu versiyada heç bir GUI yoxdur, buna görə də showplan XML faylını çıxarmalı, * .sqlplan faylı olaraq saxlamalı və SSMS -də açmalısınız. Bu çətindir. XEvents SQL 2005 və ya daha əvvəl mövcud deyildi. Beləliklə, SQL 2012 və ya daha sonra deyilsinizsə, burada yerləşdirilən digər cavablardan birini şiddətlə təklif edərdim.

paylaşmaq

Sorğuların optimallaşdırılması və icra planı üçün uyğun ağacların təqdim edilməsinə dair bəzi nümunələrə baxaq. Şəkil 27 sorğu və onun icra planını göstərir. Bu nümunədə, Client 1 cədvəlinin Ad sahəsində indeksi yoxdur. Adı = 'Petrov 4 şərti ilə məlumat seçmək üçün cədvəl satırının taranması istifadə olunur (yəni bütün cədvəl indeks istifadə edilmədən ardıcıl olaraq oxunur).

Pirinç. 27.

Şəkil 28 eyni cədvəl və onun icra planı üçün başqa bir sorğu göstərir. Bu nümunədə, Customer 1 cədvəlində CustomerID sahəsində qeyri -klaster indeksi var. Məlumatı Müştəri Kodu = 2 şərti ilə seçmək üçün əvvəlcə indeks axtarışından istifadə olunur və tapılan RID dəyəri ilə ClientT cədvəlinin müvafiq məlumat səhifəsinə daxil olur.Beləliklə, indeksli bir sahə üçün şərt olan bir sorğu istifadə edə bilər. bir indeks istifadə edərək optimal bir plan. İndekslənməyən bir sahədəki şərti sorğu üçün plandakı indeksdən istifadə etmək olmaz.

Pirinç. 28.

Şəkillər 29, 30, qruplaşdırılmış indeksi olan Müştəri cədvəlinə qarşı sorğuların icra planlarını göstərir. Rəqəmlər göstərir ki, sorğuda vəziyyəti təyin etmək üçün hansı sahədən istifadə olunmasından asılı olmayaraq, Kümelenmiş İndeksdən istifadə olunur (MS SQL Server -də məlumatların saxlanmasının təşkili bölməsində, qruplaşdırılmış bir indeksin indeks ağacını və məlumatları birləşdirdiyi göstərilmişdir). Fərq ondadır ki, əgər sorğudakı şərt indekslənmiş sahə ilə müəyyən edilirsə (bu nümunədə Müştəri ID sahəsi), onda indeks ağacında axtarışdan istifadə olunur (Kümelenmiş İndeks Axtarmaq, Şəkil 30). Əks təqdirdə, indeks ağacının ardıcıl taramasından istifadə olunur (Kümelenmiş İndeks Taraması, Şəkil 29).

Pirinç. 29.

Pirinç. otuz

Şəkillər 31, 32, StateProvincelD sütununda yığılmamış indeksi olan new_addresses cədvəlinə qarşı sorğuların icra planlarını göstərir. A.StateProvincelD = 32 şərtinə görə ilk sorğu çox seçicidir (19814 -dən bir sətir seçilir):

SEÇİN * New_addresses -dən bir harada a.StateProvincelD = 32;

Bu vəziyyətdə, planın quruluşundan (Şəkil 31), optimallaşdırıcının StateProvincelD sütunu üçün indeks axtarışından istifadə etdiyini və sonra tapılan R1D üçün cədvəl məlumatları səhifəsinə keçdiyini görə bilərik. Nested Loops ifadəsi (içəri döngə) tək bir cədvələ qarşı bir sorğu üçün göstərilir (xarici döngə indeks axtarışdır, daxili bir masa zəngidir).

Pirinç. 31.

A.StateProvincelD = 9 şərti üçün ikinci sorğu aşağı seçicidir (şərti təmin edən satır sayının ümumi satır sayına nisbəti 23%-dir):

SEÇİN * FROM new_addresses WHERE a.StateProvincelD -9;

Bu vəziyyətdə, plan quruluşundan (Şəkil 32), optimallaşdırıcının StateProvincelD sütunu üçün indeks axtarışından istifadə etmədiyini, ancaq birbaşa məlumat cədvəlinin səhifələrinə istinad etdiyini görmək olar (indeks istifadə edilmir, cədvəl skan edildi).

Pirinç. 32.

WITH (INDEX (0)) optimallaşdırıcı ipucundan istifadə nümunəsinə baxaq. Masada heç bir qruplaşdırılmış indeks yoxdursa, INDEX (0) cədvəl taramaları tələb edir. Kümelenmiş bir indeks mövcud olduqda, INDEX (0) qruplaşdırılmış indeks taramasını təyin edir.

AdventureWorks istifadə edin;

SEÇİN * Oğul başına. Ünvan harada a.StateProvincelD = 32.

Sorğu icra planı ağacı Şəkil 33 -də göstərilmişdir.

Pirinç. 33.

AdventureWorks istifadə edin;

SEÇİN * W1TH OLARAK Şəxsi Ünvan (INDEX (0))

Harada a.StateProvincelD = 32.

Sorğu icra planı ağacı Şəkil 34 -də göstərilmişdir. Bu sorğunun qeyri -klasterli indeks axtarışından istifadə etmədiyini görə bilərsiniz.

Pirinç. 34.

Cədvəl birləşmələrini idarə etmək üçün müxtəlif üsullarla sorğu icra planlarının nümunələrinə baxaq. HumanResources.Employee və HumanResources.EmployeeAddress cədvəllərinin birləşdirilmiş sütunları əsas açarlara və buna görə də qruplaşdırılmış indekslərə malikdir. Şəkil 35, HumanResources.EmployeeAddress cədvəlinin EmployeelD və AddressID sahələrində qruplaşdırılmış kompozit indeksə malik olduğunu göstərir.

Pirinç. 35.

İlk sorğu e.EmployeelD = 10 şərtini göstərdi:

AdventureWorks istifadə edin;

SEÇİN * HumanResources.Employee AS e JOIN HumanResources.EmployeeAddress ON ON e.EmployeelD = a.EmployeelD AND e.EmployeelD = 10;

Sorğu planı ağacı Şəkil 36 -da göstərilmişdir. Texnikanın Nested Loops bağlantısını idarə etmək üçün istifadə edildiyini görə bilərsiniz. Əlavə bir filtr (e.EmployeelD = 10) olduğu üçün optimallaşdırıcı yuvalı döngələrdən istifadə etmək qərarına gəlir.

nəticə cərgəsini bir sətrə kəsər. Birincisi, uyğun gələn sıra üçün HumanResources.Employee cədvəlində bir indeks axtarışı aparılır. Sonra, HumanResources.EmployeeAddress cədvəlini axtarın. Kümelenmiş İndeks Axtarmaq operatoru, indekslərin axtarış qabiliyyətlərindən istifadə edərək sıraları qruplaşdırılmış indeksdən alır.

Pirinç. 36.

Bu nümunədə, HumanResources.Employee və HumanRe- cədvəlləri

işçilərin ünvanı. Bu ardıcıllıqla bu cədvəllər də sorğuda göstərilir (FROM HumanResources.Employee AS e JOIN HumanResources.Employee Address AS).

Sorğuda cədvəl ardıcıllığını dəyişdirək:

AdventureWorks istifadə edin;

SEÇİN * HumanRe mənbələrindən. Ünvanını İnsan Resurslarına QOŞULMAQ kimi işə götürün. = a.EmployeelD və e.EmployeelD = 10;

Plan ağacı dəyişməz qalacaq. Bunlar. sorğudakı cədvəllərin ardıcıllığının dəyişdirilməsi onların işlənmə ardıcıllığına təsir etməmişdir. Bunun səbəbi, optimallaşdırıcının HumanResources.Employee cədvəlindən ən yaxşı seçim olmasını təyin etməsidir (tapılan bir sıra üçün masaya bir zəng edilir)

HumanResources.EmployeeAddress tapılan dəyərə görə). Fərqli bir cədvəl işləmə ardıcıllığından istifadə edirsinizsə, onda HumanResources.EmployeeAddress cədvəlinin hər bir satırı üçün HumanResources.Employee cədvəlinə dəfələrlə daxil olmaq lazımdır və sorğunun icra dəyəri daha yüksək olacaqdır.

Şərti sorğudan çıxararsanız:

AdventureWorks istifadə edin;

SEÇİN * HumanResources.Employee AS e JOIN HumanResources.EmployeeAddress ON ON e.EmployeelD = a.EmployeelD,

sonra əlaqəni idarə etmək texnikası dəyişəcək. Sorğu icra planı ağacı Şəkil 37 -də göstərilmişdir.

Pirinç. 37.

Bu sorğuda e.EmployeelD = 10 cümləsi yoxdur və nəticə çox sayda satır ehtiva edir, lakin indeksə görə sıralanır. Bu vəziyyətdə optimallaşdırıcı birləşmə birləşmə metodunu seçir. Qoşulun Birləşin.

Sorğunun icra planını nəzərdən keçirin:

AdventureWorks istifadə edin;

SEÇİN *

Dövlət Statistika İdarəsində = Ştat VəziyyətiD

Person.Address cədvəli və onun açarları və indeksləri Şəkil 38 -də göstərilmişdir.

Pirinç. 38.

Person.StateProvince cədvəli, onun açarları və indeksləri Şəkil 39 -da göstərilmişdir.

Pirinç. 39.

Sorğu icra planı ağacı Şəkil 40 -da göstərilmişdir.

Pirinç. 40.

Görülə bilər (Şəkillər 38, 39) birləşmədə iştirak edən cədvəllərin qruplaşdırılmış indekslərə malik olduğu və plan ağacının hər bir cədvəl üçün qruplaşdırılmış indeksin müvafiq taramasından istifadə etdiyi. Bağlantı idarəetmə texnikası, əlaqəni bağlamaqdır. Bunun səbəbi, Person.Address cədvəlindəki qeydlərin StateProvincelD sahəsinə görə sıralanmamasıdır.

Bir əlaqə sifarişinə bir nümunə verək. Yuxarıda belə bir sorğu vardı:

AdventureWorks istifadə edin;

SEÇİN * FROM Person.Address JOIN Person.StateProvince s

A.StateProvincelD = s.StateProvincelD

və əlaqəni idarə etmə texnikasını istifadə edən bir icra planı - əlaqəni kəsmək (Hash Match).

Bir sorğuya bir işarə əlavə edərkən

AdventureWorks istifadə edin;

SEÇİN * FROM Person.Address JOIN Person.StateProvince s

Dövlət Statistika İdarəsində = Ştat VəziyyətiD

SEÇENEK (QOŞULMA),

əlaqə emalı texnikası dəyişir (plan ağacı Şəkil 41 -də göstərilmişdir). İstifadə olunan texnika birləşmə birləşməsidir. Şəkil sıralama əməliyyatının (Sort) əvvəlcədən yerinə yetirildiyini göstərir.

Tarix dünya qədər qədimdir. İki masa:

  • Şəhərlər - 100 unikal şəhər.
  • İnsanlar - 10 milyon insan. Bəzi insanlar üçün şəhər göstərilməyə bilər.
İnsanların şəhərlər arasında paylanması bərabərdir.
Cites.Id, Cites.Name, People .CityId sahələri üçün indekslər mövcuddur.

Sitatlara görə sıralanan ilk 100 nəfərlik qeydləri seçməlisiniz.

Qollarımızı yuvarlayın, şənliklə yazırıq:

Ən yaxşı 100 p Adı, c. İnsanlardan Şəhər olaraq adlandırın s
c.Name tərəfindən sifariş

Bu bizə belə bir şey verəcəkdir:

6 saniyədə ... (MS SQL 2008 R2, i5 / 4Gb)

Amma necə ola bilər! 6 saniyə haradan gəldi?! İlk 100 girişdə yalnız Almatı olacağını bilirik! Axı 10 milyon qeyd var ki, bu da şəhər başına 100 min deməkdir, belə olmasa belə, siyahıdakı birinci şəhəri seçə bilərik və ən azı 100 sakinin olub olmadığını yoxlaya bilərik.

Statistikaya malik olan SQL serveri niyə bunu etmir:

İnsanlar s -dən * seçin
c.Id = p.CityId üzrə C şəhərlərinin soluna qoşulun
harada p.CityId
in (Şəhərlər sırasına görə ada görə ilk 1 id seçin)
c tərəfindən sifariş.

Bu sorğu saniyədən az bir müddətdə təxminən 100K qeydini qaytarır! Axtardığımız 100 qeydin olduğundan əmin olduq və çox tez geri qaytardıq.

Ancaq MSSQL hər şeyi plana uyğun olaraq edir. Və "təmiz qaynaşma" (c) planı var.

Bilənlər üçün bir sual:
Nəticəni ilk sorğuda 10 qat daha sürətli əldə etmək üçün SQL sorğusunu düzəltmək və ya serverdə bir hərəkət etmək necə lazımdır?

P.S.
CƏDVƏL OLUN. (


unikal identifikator
AÇIQ
GET

CƏDVƏL OLUN. (
unikal identifikator NULL deyil,
nvarchar (50) NULL DEYİL,
AÇIQ
GET

P.P.S
Bacakların böyüdüyü yer:
Tapşırıq olduqca realdır. Əsas varlığı olan bir masa var, "ulduz" prinsipinə görə bir çox ölçülər ondan ayrılır. İstifadəçinin, sahələrə görə çeşidlənməsi təmin edərək onu griddə göstərməsi lazımdır.
Əsas cədvəlin müəyyən bir ölçüsündən başlayaraq, çeşidləmə eyni (həddindən artıq) dəyərlərə malik bir pəncərənin seçilməsinə (məsələn, "Almatı" kimi) qədər azalır, lakin sistem dəhşətli dərəcədə yavaşlamağa başlayır.
Həm kiçik, həm də böyük insanlar cədvəli ölçüləri ilə səmərəli işləyəcək BİR parametrli sorğuya sahib olmaq istərdim.

P.P.P.S
Maraqlıdır ki, əgər City NotNull olsaydı və InnerJoin istifadə olunsaydı, sorğu dərhal icra ediləcəkdi.
Şəhər sahəsinin NotNull olsaydı da LeftJoin istifadə edildiyinə baxmayaraq, sorğu yavaşlayır.

Şərhlərdə bir fikir: Əvvəlcə bütün InnerJoins və sonra Union by Null dəyərlərini seçin. Sabah bu və digər çılğın fikirləri yoxlayacağam)

P.P.P.P.S Mən sınadım. İşlədi!

AS AS ilə
ən yaxşı 100 -ü seçin Adı, c.İnsanlardan Şəhər olaraq adlandırın s
INNER c.Id = p.CityId şəhərlərinə c qoşulun
ASC tərəfindən sifariş verin
BİRLİK
ən yaxşı 100 p seçin. Ad, NULL City from People p
Harada p.CityId NULLDUR
YARDIMDAN TOP 100 * SEÇİN

Eyni şərtlərdə 150 ​​millisaniyə verir! təşəkkürlər


2021
maccase.ru - Android. Markalar. Dəmir. xəbərlər