Ana içeriğe geç
Kesit SQL
İleri · Sorgu Optimizasyonu

Yanlış optimizasyon: hızlı görünen ama işe yaramayan ya da sonucu bozan değişiklikler

Sonucu değiştiren yeniden yazımlar, efsaneler (COUNT(1), EXISTS), NOLOCK, her sütuna indeks, ipucu kullanımı, ölçmeden karar.

Uygulamada aç, 8 alıştırmayı çözÜcretsiz, hesap gerekmez, kurulum yok.

Bu sayfa dersin okuma sürümüdür. Metin bir kutuyu çalıştırmanı ya da adıma geçmeni söylüyorsa dersi uygulamada aç.

En tehlikeli optimizasyon sonucu değiştirendir

Yavaş rapor can sıkar, yanlış rapor kararı bozar. Aşağıdakilerin hepsi gerçek işlerde sık görülür. Önce sonucu bozanlara, sonra işe yaramayanlara bakalım.

Sonucu bozan "hızlandırmalar"

DeğişiklikNeden yapılırNe bozulur
UNION yerine UNION ALLTekilleştirme adımı kalksınİki kolda da çıkan satır iki kez sayılır
OR yerine iki kollu UNION ALLHer kol kendi indeksini kullansınAynı sebeple çoğalma
LEFT JOIN yerine JOINDaha hızlı planEşleşmeyen satırlar kaybolur
COUNT(DISTINCT x) yerine COUNT(x)Tekilleştirme pahalıÇoğalan satırlar sayılır
BETWEEN ile tarih aralığıKısa yazımSon günün saatli kayıtları düşer
NOT IN ile NOT EXISTS arasında geçiş"Biri daha hızlı"Alt sorguda NULL varsa sonuç değişir
WITH (NOLOCK)Kilit beklemesinKirli okuma: geri alınacak değişiklikler okunur, satır atlanabilir ya da iki kez okunabilir

Son satır için not: SQL Server'da NOLOCK, READUNCOMMITTED demektir. Kilit beklemesi sorununu hız sorunu sanıp bir finansal raporun sonucunu riske atma. Çoğu zaman satır sürümlemeye dayalı okuma (READ COMMITTED SNAPSHOT) daha doğru yoldur.

İşe yaramayanlar: efsaneler

"COUNT(1), COUNT(*)'tan hızlıdır"

Aynı tablodaki iki plan aşağıda. Aynı işlem, aynı sayfa sayısı.

PostgreSQL çıktılarıBu derslerdeki PostgreSQL planları elle yazılmadı. Aynı veriyle PostgreSQL 16.4 üzerinde (PGlite, tarayıcıda çalışan WASM sürümü) üretildi. VACUUM ANALYZE çalıştırıldı, planlama satırları kısalık için çıkarıldı. Sayılar kendi sunucunda farklı olur; okuma biçimi aynıdır.
EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF)
SELECT COUNT(*) FROM lk_orders;

Gerçek çıktı

Aggregate  (cost=157.90..157.91 rows=1 width=8) (actual rows=1 loops=1)
  Buffers: shared hit=8
  ->  Index Only Scan using lk_orders_restaurant_id_idx on lk_orders  (cost=0.28..139.95 rows=7178 width=0) (actual rows=7178 loops=1)
        Heap Fetches: 0
        Buffers: shared hit=8
EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF)
SELECT COUNT(1) FROM lk_orders;

Gerçek çıktı

Aggregate  (cost=157.90..157.91 rows=1 width=8) (actual rows=1 loops=1)
  Buffers: shared hit=8
  ->  Index Only Scan using lk_orders_restaurant_id_idx on lk_orders  (cost=0.28..139.95 rows=7178 width=0) (actual rows=7178 loops=1)
        Heap Fetches: 0
        Buffers: shared hit=8

"İndeks her zaman hızlandırır"

Seçiciliği düşük koşulda indeks yararsız kalabilir. Bu veride yaygın bir değerle yapılan okuma, Bitmap Heap Scan kullansa da tablonun tamamından çok sayfa okudu:

Bitmap Heap Scan on bank_txns  (cost=234.88..881.67 rows=20463 width=10) (actual rows=20520 loops=1)
  Recheck Cond: ((txn_type)::text = 'kart_harcama'::text)
  Heap Blocks: exact=390
  Buffers: shared hit=410
  ->  Bitmap Index Scan on ix_tip  (cost=0.00..229.76 rows=20463 width=0) (actual rows=20520 loops=1)
        Index Cond: ((txn_type)::text = 'kart_harcama'::text)
        Buffers: shared hit=20

"Her sütuna indeks ekleyelim"

Her indeks her yazmaya biner, çakışan indeksler boşa yer kaplar. SQL Server belgesi "iyileştiriciye seçenek olsun" diye çok sayıda indeks oluşturmaya karşı uyarır: veri değişikliğini yavaşlatır, eşzamanlılık sorunu çıkarabilir.

"Sorguya ipucu yazarım, motor doğru planı bulur"

İpucu bugünkü veriye göre kilitler. Veri büyüyünce doğru plan değişir, ipucu kalır. SQL Server belgesi ipuçlarını son çare sayar. PostgreSQL'de ise standart bir sorgu ipucu sözdizimi yoktur.

"LIMIT ekledim, fatura düştü"

BigQuery belgesine göre kümelenmemiş tabloda düşmez. Sıralı sorguda da LIMIT her zaman işi azaltmaz: tüm satırlar sıralanmak zorunda kalabilir.

"CTE'ye alınca hızlandı"

Yazım değiştirmek işi azaltmaz. Motor CTE'yi gömüyorsa plan aynı kalır, saklıyorsa kötüleşebilir. Ölç.

Ölçme hataları

Kontrol sorusu"Bu değişiklikten sonra sonuç aynı mı, hangi sayı düştü, karşılığında ne ödedim?" Bu üçünü söyleyemiyorsan optimizasyon bitmedi.
Alıştırmalara geç (8)