PostgreSQL JSON Sorgularını Hızlandırma: İndeksleme Stratejileri
PostgreSQL'de JSON depolamak kolay, ama milyonlarca satır içinde hızlı sorgu yapmak başka bir mesele. Doğru indeksleme olmadan -> ve @> operatörleriyle yapılan sorgular tablo taraması yapar ve sistem yavaşlar.
JSON verilerini sorgulamak için iki ana indeks türü vardır: GIN (Generalized Inverted Index) ve JSONB. JSONB, JSON'ın binary formudur ve indeksleme için daha hızlıdır. Eğer JSON depoluyorsan, json yerine jsonb kullan.
Bir örnek verelim. Kullanıcı profil bilgilerini JSON olarak tutan bir tablomuz olsun:
1CREATE TABLE users (2id SERIAL PRIMARY KEY,3profile JSONB NOT NULL4);56INSERT INTO users (profile) VALUES7('{"name": "Ali", "city": "Istanbul", "age": 28}'::jsonb),8('{"name": "Ayse", "city": "Ankara", "age": 32}'::jsonb),9('{"name": "Mehmet", "city": "Istanbul", "age": 25}'::jsonb);Şimdi city alanına göre sorgulama yapacak bir sorgu yazalım:
1SELECT * FROM users WHERE profile @> '{"city": "Istanbul"}'::jsonb;Bu sorgu ilk başta çalışır ama tablo büyüdüğünde yavaşlar. Hız için GIN indeksi oluştur:
1CREATE INDEX idx_users_city ON users USING GIN (profile);Bu indeks tüm JSON anahtarlarını indeksler. Eğer sadece belirli bir alana ihtiyacın varsa, daha verimli bir indeks yap:
1CREATE INDEX idx_users_city_specific ON users USING GIN ((profile -> 'city'));İndeks oluşturduktan sonra aynı sorguyu çalıştır:
1EXPLAIN ANALYZE SELECT * FROM users WHERE profile @> '{"city": "Istanbul"}'::jsonb;Çıktıda "Bitmap Index Scan" göreceksin; bu, indeksin kullanıldığını gösterir. Tablo taraması (Seq Scan) yerine indeks taraması yapılıyor.
Daha karmaşık bir durumda, örneğin yaş aralığına göre sorgulamak istersen:
1SELECT * FROM users WHERE (profile -> 'age')::int > 26;Bu durumda indeksin tam yararlanabilmesi için cast işlemini indeks tanımına dahil et:
1CREATE INDEX idx_users_age ON users USING GIN (profile jsonb_path_ops);jsonb_path_ops operatörü sınırlı ama daha hızlı ve daha az yer kaplar.
Sık yapılan hata: JSON alanını indekslemeden binlerce satır sorgulamak. Başlangıçta fark etmezsin ama veri büyüdüğünde sistem donup kalır. Her zaman EXPLAIN ANALYZE ile sorgunun indeks kullanıp kullanmadığını kontrol et. İndeks yoksa sorgu planı "Seq Scan" gösterir; bu durumda hemen indeks ekle. Ayrıca, indeksi oluştururken CONCURRENTLY parametresini kullan; böylece tablo kilitlenmez ve uygulamaya hizmet vermeye devam eder.
0 yorum