Təsəvvür elə, sən bir app yazırsan və birdən sənin sorğularından biri bazada ən bahalıya çevrilir. Artıq app-də ləngimələr və problemlər hiss edirsən. Bax, məhz bu anda EXPLAIN səhnəyə çıxır və başa düşməyə kömək edir ki, harada nə səhv gedir. EXPLAIN əsasında sorğuları optimizasiya etmək sənə resurslara qənaət etməyə, vaxt udmağa və istifadəçilərin app-dən aldığı təəssüratı yaxşılaşdırmağa imkan verir.
EXPLAIN — bu, PostgreSQL-in içini görmək və bazanın sorğunu necə icra edəcəyini anlamaq üçün sənin yolundur. O göstərir ki, index istifadə olunacaq, yoxsa tam cədvəl scan olacaq, optimizer hansı addımları atacaq, hansı ardıcıllıqla gedəcək və arada hansı ölçüdə nəticələr yaranacaq.
Başqa sözlə, EXPLAIN sənə sorğunun icrasından nə gözləmək lazım olduğunu başa düşməyə kömək edir: nə qədər “ağırdır”, neçə sətrin işlənəcəyi gözlənilir və hansı resurslar istifadə olunacaq. Bu, sorğu birdən ləngiyəndə və səbəbini tapmaq lazım olanda əvəzolunmaz alətdir.
EXPLAIN — qaranlıqda fənər kimidir: onunla “kapotun altında” nə baş verdiyini və harada nəsə səhv getdiyini görmək olur.
EXPLAIN komandasının sintaksisi
Gəlin EXPLAIN komandasının əsas sintaksisinə baxaq:
EXPLAIN sənin_SQL_sorgun;
Sorğu nümunəsi:
EXPLAIN SELECT * FROM students WHERE age > 20;
Bu komandanı işə salanda, PostgreSQL sorğunu icra etməyəcək. Bunun əvəzinə execution plan göstərəcək. Bu, tikintidən əvvəl eskiz kimidir — nəyin necə olacağını əvvəlcədən görmək faydalıdır, nəyisə sındırmazdan qabaq.
Çıxış nümunəsi belə ola bilər:
Seq Scan on students (cost=0.00..35.00 rows=7 width=37)
Filter: (age > 20)
Bu çıxış bir az qorxulu görünə bilər, amma narahat olma — indi əsas hissələri izah edəcəyik.
Əsas execution plan-ın izahı
Gəlin həmin nəticəni analiz edək:
Seq Scan on students — bu o deməkdir ki, PostgreSQL
studentscədvəlini tam scan edəcək (ardıcıl scan). Bu həmişə pis deyil, amma böyük cədvəllərdəSeq Scanyavaş ola bilər.cost=0.00..35.00 — bu əməliyyatın icra xərclərinin qiymətləndirilməsidir:
Startup Cost: əməliyyatın start xərci (burada0.00).Total Cost: əməliyyatın tam başa çatdırılması üçün ümumi xərc (burada35.00).
rows=7 — PostgreSQL düşünür ki,
age > 20şərti 7 sətr qaytaracaq. Buna “cardinality” deyilir. Əgər qəribə qiymətləndirmələr görürsənsə, bu, cədvəlin statistikası köhnədir demək ola bilər.width=37 — bir sətrin orta ölçüsü (baytlarla).
Filter: (age > 20) — göstərir ki, PostgreSQL hər sətri yoxlayaraq filter tətbiq edəcək.
Beləliklə, EXPLAIN çıxışı sənə PostgreSQL-in strategiyaları və ehtimalları barədə təsəvvür verir. Bu məlumatı optimizasiya üçün istifadə edə bilərsən.
EXPLAIN komandasının opsiyaları
Sadə EXPLAIN çıxışı artıq faydalıdır, amma onu aşağıdakı opsiyalarla dəyişə bilərsən:
ANALYZE
Bu opsiya ilə PostgreSQL təkcə execution plan göstərmir, həm də sorğunu icra edib real nəticələri verir. Nümunə:
EXPLAIN ANALYZE SELECT * FROM students WHERE age > 20;
Bu, PostgreSQL-in ehtimalları ilə real icranı müqayisə etməyə imkan verir ki, nə qədər üst-üstə düşürlər.
VERBOSE
Daha detallı məlumat göstərir, dərin analiz üçün faydalıdır. Nümunə:
EXPLAIN VERBOSE SELECT * FROM students WHERE age > 20;
BUFFERS
Sorğunun icrası zamanı yaddaş buffer-larının istifadəsini göstərir. ANALYZE ilə birlikdə istifadə olunur:
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM students WHERE age > 20;
COSTS
Xərclər (cost) barədə məlumatı gizlətmək və ya göstərmək istəyirsənsə, bu opsiyanı istifadə et:
EXPLAIN (COSTS OFF) SELECT * FROM students WHERE age > 20;
FORMAT
Plan çıxışı başqa formatlarda da ola bilər, məsələn JSON və ya XML. Nümunə:
EXPLAIN (FORMAT JSON) SELECT * FROM students WHERE age > 20;
EXPLAIN istifadəsinə nümunə
Tutaq ki, university adlı bazada students cədvəlin var. Deyək ki, 20 yaşdan yuxarı bütün tələbələri tapmaq istəyirsən:
EXPLAIN SELECT * FROM students WHERE age > 20;
Çıxış belə ola bilər:
Seq Scan on students (cost=0.00..35.00 rows=7 width=37)
Filter: (age > 20)
Dediyimiz kimi, bu ardıcıl scan-dır (Seq Scan) və böyük cədvəllər üçün effektiv olmaya bilər.
İndi isə age sütunu üzrə index yaradaq və plan dəyişəcəkmi baxaq:
CREATE INDEX age_index ON students(age);
EXPLAIN SELECT * FROM students WHERE age > 20;
Çıxış:
Index Scan using age_index on students (cost=0.15..4.23 rows=7 width=37)
Index Cond: (age > 20)
İndi PostgreSQL index scan (Index Scan) istifadə edir, bu da adətən böyük cədvəllər üçün daha sürətlidir.
Tipik suallar və səhvlər
Niyə sorğum index olmasına baxmayaraq yavaş işləyir?
Bəlkə də sorğu çoxlu sətir qaytarır və index istifadə etmək sərfəli deyil. Index keyfiyyətsiz və ya köhnə ola bilər.
EXPLAIN çıxışını başa düşmək çətindirsə nə edim?
Sadə sorğulardan başla və execution plan-ın node-larını bir-bir öyrən.
Cədvəlin statistikası köhnədirsə necə bilmək olar?
ANALYZE students komandasını işə sal
EXPLAIN-i ANALYZE olmadan nə vaxt istifadə etməli?
Əgər planı real icra olmadan görmək istəyirsənsə (məsələn, data dəyişən sorğular üçün).
GO TO FULL VERSION