CodeGym /Kurslar /SQL SELF /İcra planının interpretasiyası: node-ların oxunması və tə...

İcra planının interpretasiyası: node-ların oxunması və təhlili (`Seq Scan`, `Index Scan`, `Hash Join`)

SQL SELF
Səviyyə , Dərs
Mövcuddur

Bu gün baxacağıq ki, PostgreSQL-in icra planındakı node-lar nədir, onları necə oxumaq lazımdır və ən əsası, nəyinsə səhv getdiyini necə başa düşmək olar. Sən öyrənəcəksən ki, niyə sənin database bəzən resurs yeyən Seq Scan-ı seçir, halbuki artıq index var, bəlkə də bir neçə dənə.

PostgreSQL sorğunun icra planını quranda onu mərhələlərə bölür, bunlara node deyilir. Hər bir node — database serverinin sənin sorğunu işlətmək üçün etdiyi bir "addım"dır. Əsas node tiplərinə daxildir:

Sequential Scan (Seq Scan)

Seq Scan və ya ardıcıl skan — cədvəldən məlumat çıxarmağın ən sadə yoludur. PostgreSQL sadəcə cədvəli götürür, sətirləri bir-bir oxuyur və yoxlayır ki, onlar sənin sorğunun şərtlərinə uyğundurmu.

Seq Scan nə vaxt istifadə olunur?
Seq Scan aşağıdakı hallarda tətbiq olunur:

  • Cədvəldə sorğunu sürətləndirmək üçün uyğun index yoxdur.
  • Filter şərti çox ümumidir, yəni index faydalı olmur (məsələn, 50%-dən çox məlumat çıxarılırsa).
  • PostgreSQL hesab edir ki, cədvəli ardıcıl oxumaq index-dən istifadə etməkdən daha sürətlidir (bəzən çox kiçik cədvəllərdə belə olur).
EXPLAIN SELECT * FROM students WHERE age > 18;

Nümunə nəticə:

Seq Scan on students  (cost=0.00..35.50 rows=10 width=50)
  Filter: (age > 18)

Seq Scan on students-ə fikir ver — bu o deməkdir ki, PostgreSQL "students" cədvəlini tam oxuyacaq.

Seq Scan problemləri: Əgər cədvəl böyükdürsə, ardıcıl skan çox vaxt apara bilər.

Index Scan

Index Scan — məlumatı index vasitəsilə oxumaqdır. PostgreSQL-də index yaradanda, bu sanki cədvəlin "mündəricatını" düzəltmək kimidir. Əgər sorğu index-dən istifadə edə bilirsə, PostgreSQL cədvəli tam oxumur, yalnız lazım olan hissələri götürür.

Index Scan nə vaxt istifadə olunur?

  • Sorğuda index olan sütun üçün filter şərti var (məsələn, WHERE).
  • =, <, >, BETWEEN və s. kimi müqayisə əməliyyatları istifadə olunur.
CREATE INDEX idx_students_age ON students(age);

EXPLAIN SELECT * FROM students WHERE age = 18;

Nümunə nəticə:

Index Scan using idx_students_age on students  (cost=0.15..8.27 rows=1 width=50)
  Index Cond: (age = 18)

Burada Index Scan using idx_students_age göstərir ki, PostgreSQL idx_students_age index-dən istifadə edir. Sətir-sətir cədvəl oxumaq əvəzinə, index vasitəsilə daha sürətli giriş olur.

Index Scan üstünlükləri:

  • Böyük cədvəllərdə sorğuların sürətini xeyli artırır.
  • Diskdən oxunan məlumatın miqdarını azaldır.

Index Scan problemləri:
Əgər sorğun çoxlu məlumat qaytarırsa (məsələn, cədvəlin yarısından çoxunu), index-dən istifadə bəzən Seq Scan-dan da yavaş ola bilər.

Hash Join

Hash Join iki cədvəli join şərti əsasında birləşdirmək üçün istifadə olunur (məsələn, ON students.course_id = courses.id). PostgreSQL cədvəllərdən birinin (adətən kiçik olanın) hash cədvəlini yaradır və digər cədvəldə uyğunluqları tapmaq üçün ondan istifadə edir.

Hash Join nə vaxt istifadə olunur?

  • Cədvəllər INNER JOIN, LEFT JOIN və s. ilə birləşdiriləndə.
  • PostgreSQL hesab edir ki, Hash Join digər join metodlarından daha effektivdir.
EXPLAIN
SELECT * 
FROM students 
JOIN courses ON students.course_id = courses.id;

Nümunə nəticə:

Hash Join  (cost=25.00..50.00 rows=10 width=100)
  Hash Cond: (students.course_id = courses.id)
  -> Seq Scan on students  (cost=0.00..20.00 rows=10 width=50)
  -> Hash  (cost=15.00..15.00 rows=10 width=50)
       -> Seq Scan on courses  (cost=0.00..15.00 rows=10 width=50)

Burada Hash Join iki cədvəli birləşdirir. Fikir ver ki, PostgreSQL əvvəlcə hər iki cədvəl üçün Seq Scan edir, sonra isə hash cədvəli (Hash) qurur.

Hash Join üstünlükləri:

  • Orta ölçülü cədvəllər üçün sürətli işləyir.
  • Çoxlu sətir olan cədvəlləri birləşdirmək üçün effektivdir.

Hash Join problemləri:
Əgər hash cədvəlinin ölçüsü mövcud yaddaşı aşırsa, PostgreSQL onu diskdə saxlayacaq və bu da join-i xeyli yavaşladır.

İcra planının təhlili nümunəsi

Gəlin real bir nümunəyə baxaq.

Sorğu:

EXPLAIN ANALYZE
SELECT *
FROM students
JOIN courses ON students.course_id = courses.id
WHERE students.age > 18;

Nəticə:

Hash Join  (cost=35.00..75.00 rows=5 width=100) (actual time=1.00..2.50 rows=5 loops=1)
  Hash Cond: (students.course_id = courses.id)
  -> Seq Scan on students  (cost=0.00..40.00 rows=10 width=50) (actual time=0.50..1.00 rows=7 loops=1)
        Filter: (age > 18)
        Rows Removed by Filter: 3
  -> Hash  (cost=25.00..25.00 rows=5 width=50) (actual time=0.30..0.30 rows=5 loops=1)
       -> Seq Scan on courses  (cost=0.00..20.00 rows=5 width=50) (actual time=0.20..0.25 rows=5 loops=1)
Planning Time: 0.50 ms
Execution Time: 3.00 ms

Interpretasiya:

  1. Hash Join: Əsas node. PostgreSQL studentscourses cədvəllərini birləşdirir.
    • actual time: 1.00-dan 2.50 ms-ə qədər.
    • rows=5: sorğu 5 sətir qaytardı.
  2. Daxili node-lar:
    • Seq Scan on students: students cədvəlini ardıcıl oxuyur və (age > 18) filtrini tətbiq edir.
    • Rows Removed by Filter = 3: 3 sətir şərtə uyğun gəlmədi.
    • Hash: PostgreSQL courses cədvəli üçün hash cədvəli yaradır.

Node-ların müqayisəsi və seçimi

İcra planını təhlil edəndə əsas məsələ odur ki, PostgreSQL-in niyə məhz bu və ya digər məlumat işləmə metodunu seçdiyini başa düşəsən. Bəzən müdaxilə etmək lazım olur, məsələn, index əlavə etmək və ya sorğunu dəyişmək. Bir neçə məsləhət:

  • Böyük cədvəldə Seq Scan görürsənsə, index barədə düşün.
  • Hash Join çox yavaşdırsa, PostgreSQL üçün mövcud yaddaşı yoxla.
  • EXPLAIN ANALYZE istifadə et ki, proqnozlaşdırılan və real metrikləri (rows, time) müqayisə edəsən.

Bu mərhələdə artıq sorğuların icra planlarını oxumaq və onların node-larını interpretasiya etmək barədə əsas anlayışa maliksən. Növbəti dərslərdə optimizasiya problemləri və onların həlli barədə danışacağıq.

1
Sorğu/viktorina
, səviyyə, dərs
Əlçatan deyil
Sorgunun icra planı
Sorgunun icra planı
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION