SARGable ne demek?
Search ARGument-able: indeks üzerinde arama yapılabilen koşul. Kural basit: sütunu yalnız bırak. Sütun bir fonksiyonun veya işlemin içine girerse motor her satırı tek tek hesaplamak zorunda kalır.
| Yavaş (SARGable değil) | Hızlı (SARGable) |
|---|---|
WHERE YEAR(order_date) = 2024 | WHERE order_date >= '2024-01-01' AND order_date < '2025-01-01' |
WHERE price * 1.2 > 1200 | WHERE price > 1000 |
WHERE SUBSTRING(email, 1, 4) = 'ayse' | WHERE email LIKE 'ayse%' |
WHERE LIKE '%gmail.com' | Ters çevrilmiş sütun, tam metin arama ya da ayrı bir alan adı sütunu |
WHERE ISNULL(city, '') = '' | WHERE city IS NULL OR city = '' |
WHERE CAST(customer_id AS VARCHAR) = '42' | WHERE customer_id = 42 (tipleri eşleştir) |
LIKE 'ayse%' çoğu motorda aralık aramasına döner. SQLite varsayılan ayarda LIKE harf duyarsız çalıştığı için normal indeksten yararlanmaz, planda SCAN görürsün. Sütunu serbest bırakmak yine doğru alışkanlıktır.Örtük tip dönüşümü
Metin sütununu sayıyla karşılaştırmak (WHERE tax_no = 1234567890) motoru her satırda dönüşüm yapmaya zorlar ve indeks kullanılamaz. SQL Server'da NVARCHAR sabiti VARCHAR sütunla karşılaştırıldığında da benzer durum olur.
Diğer sık hatalar
- SELECT *: Gereksiz sütunlar ağ ve bellek yükü getirir, kapsayan (covering) indeksi devre dışı bırakır.
- Gereksiz DISTINCT: Çoğalma bir JOIN hatasının belirtisidir; DISTINCT ile örtmek yerine nedeni düzelt.
- Satır satır işlem: İmleç veya döngüyle tek tek UPDATE yerine tek bir küme tabanlı UPDATE.
- Ilişkili alt sorgu SELECT listesinde: Her satır için çalışır; JOIN + GROUP BY veya pencere fonksiyonu genellikle daha iyidir.
- OR ile farklı sütunlar:
WHERE a = 1 OR b = 2indeksleri zor kullanır; her kolu kendi indeksiyle çalışanUNIONsorgusuna bölmek bazen hızlandırır.UNION ALLkullanacaksan ikinci kolaAND a <> 1ekle (a NULL olabiliyorsaa IS DISTINCT FROM 1); yoksa iki koşulu da sağlayan satırlar iki kez gelir. - Sayfalamada büyük OFFSET:
OFFSET 100000önceki satırların hepsini okur; anahtar tabanlı (keyset) sayfalama kullan.
Planı oku
Tahmin etme, ölç: SQL Server'da gerçek yürütme planı ve SET STATISTICS IO ON; PostgreSQL'de EXPLAIN (ANALYZE, BUFFERS); MySQL'de EXPLAIN ANALYZE; Oracle'da DBMS_XPLAN; BigQuery'de yürütme ayrıntıları ve taranan bayt.
-- SQLite EXPLAIN QUERY PLAN SELECT * FROM orders WHERE customer_id = 7; -- PostgreSQL EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders WHERE customer_id = 7; -- MySQL EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_id = 7; -- SQL Server SET STATISTICS IO, TIME ON; SELECT * FROM dbo.orders WHERE customer_id = 7; -- Oracle EXPLAIN PLAN FOR SELECT * FROM orders WHERE customer_id = 7; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);