2011-12-19 18 views
7

(language_id, state) dizinli bir sözcük tablom var.Postitlerde LIMIT kullanıldığında dizin kullanılmıyor

Sınırsız

explain analyze SELECT "words".* FROM "words" WHERE (words.language_id = 27) AND (state IS NULL); 

Bitmap Heap Scan on words (cost=10800.38..134324.10 rows=441257 width=96) (actual time=233.257..416.026 rows=540556 loops=1) 
Recheck Cond: ((language_id = 27) AND (state IS NULL)) 
-> Bitmap Index Scan on ls (cost=0.00..10690.07 rows=441257 width=0) (actual time=230.849..230.849 rows=540556 loops=1) 
Index Cond: ((language_id = 27) AND (state IS NULL)) 
Total runtime: 460.277 ms 
(5 rows) 

Limiti 100

explain analyze SELECT "words".* FROM "words" WHERE (words.language_id = 27) AND (state IS NULL) LIMIT 100; 

Limit (cost=0.00..51.66 rows=100 width=96) (actual time=0.081..0.184 rows=100 loops=1) 
-> Seq Scan on words (cost=0.00..227935.59 rows=441257 width=96) (actual time=0.080..0.160 rows=100 loops=1) 
Filter: ((state IS NULL) AND (language_id = 27)) 
Total runtime: 0.240 ms 
(4 rows) 

neden oluyor: İşte EXPLAIN için sonuçlar ANALİZ nelerdir? Her durumda kullanılacak endeksi nasıl alabilirim?

Teşekkürler.

+4

SIPARIŞ SİPARİŞİ olmayan bir LIMIT sınırlı (punto amaçlı değil) bir değer olarak görünüyor. Hangi 100 satır iade edilmeyi bekliyorsunuz? –

+0

BTW: language_id = 17 VE ISI NULL deyiminin seçiciliği nedir? kelimeler tablosunun toplam büyüklüğü nedir? – wildplasser

+0

true ... sipariş, DESC'de gerçekleşir. Bu onu yavaşlatabilir mi? Bu sütunda bir dizin gerekli mi? @wildplasser toplam boyutu 10 milyon satırdır, seçicilik yaklaşık 500.000 satırdır – alste

cevap

7

PostreSQL sorgu planlayıcısının sanırım ikinci durumda - LIMIT olanı - indeksi [LIMIT] değeri çok küçük olduğundan uygulamaya değmez. Yani sorun değil.

+0

Haklısın, Ama bundan nasıl kurtulabilirim? Aslında jsonb cin endeksini kullanıyorum ve limit 1'den dolayı bu endeks kullanılmıyor ve çok zaman alıyor. – Anurag

0

İki sorgunun farklı sayıda satır döndürmesi de garip. Sanırım içeri giriyorsun sanırım ... Uhm, eğer bir alt-seçim yaparsan? sınırı olmadan

select * from (select ...) limit 100; 
+1

"(5 satır)", sorguda kaç satır döndürdüğünü değil, açıklama planındaki satır sayısını belirtir. – Anna

3

: sıra = 540.556 döngüler = 1 toplam çalışma süresi: 460,277 ms

sınırı ile

: sıra = 100 döngüler = 1 toplam çalışma süresi: 0.240 msn bir sorun yok

İşte. Sorgunuz 500K satır verirse, daha fazla zamana ihtiyaç duyar.

3

Using EXPLAIN ve Query Planning ile ilgili PostgreSQL belgelerine bakın. Sorgu planlayıcısının LIMIT 100 kasasında bir dizin taraması üzerinde sıralı bir taramayı tercih etmesinin nedeni, sıralı taramanın daha ucuz olması.

Sorguda ORDER BY tümceyi yok, bu nedenle planlayıcı, filtre koşuluyla eşleşen ilk 100 (rastgele) satırla tamam. Bir indeks taramasının önce dizin sayfalarını okuması ve ardından ilgili satırları almak için veri sayfalarını okuması gerekir. Sıralı tarama sadece satırları almak için veri sayfalarını okumalıdır. Durumunuzda, tablo istatistikleri, filtre koşuluna uyan yeterli (rastgele) satır olduğunu gösterir. Sıralı sayfaların maliyeti, 100 satırın alınabilmesi için maliyeti, önce dizini okuma maliyetinden daha ucuz olarak kabul edilir ve ardından gerçek satırları getirir. Sınırı artırdığınızda veya daha az satır filtre koşuluyla eşleştiğinde farklı bir plan görebilirsiniz. Varsayılan ayarları ile

planlayıcısı oku rastgele sayfanın maliyeti (random_page_cost) oku sıralı sayfasında (seq_page_cost) dört katı maliyetini dikkate alır. Bu ayarlar sorgu planlarını ayarlamak için ayarlanabilir (ör. Tüm veritabanı RAM'de olduğunda okunan bir sayfa okunan sıralı bir sayfadan daha pahalı değildir ve indeks taraması tercih edilmelidir). o küresel bazda taramaları belirli tür etkinleştirmek/devre dışı bırakmak mümkün olsa da

set enable_seqscan = [on | off] 
set enable_indexscan = [on | off] 

bu sadece kullanılmalıdır ad hoc için: Ayrıca, taramaların belirli tür devre dışı/örn sağlayarak, farklı sorgu planları deneyebilir Oturum başına temelinde hata ayıklama veya sorun giderme.Sorgu planları test etmeden önce

Ayrıca aksi bir otomatik vakum (autovaccum) sonuçlarını etkileyebilecek testler arasında çalışacak, VACUUM ANALYZE words çalıştırın.