Bitmap dizin taraması ile sorgu planlarında “Cond Recheck:” satırı


21

Bu, yorumlardan önceki soruya bir dönüştür:

PostgreSQL 9.4 kullanıldığında, Recheck Cond:sorgu planlarında bitmap dizin taramasından sonra her zaman bir satır var gibi görünüyor EXPLAIN.

Olduğu gibi EXPLAINbaşvurulan soru çıkışı:

->  Bitmap Heap Scan on table_three  (cost=2446.92..19686.74 rows=8159 width=7)
      Recheck Cond: (("timestamp" > (now() - '30 days'::interval)) AND (client_id > 0))
      ->  BitmapAnd  (cost=2446.92..2446.92 rows=8159 width=0)
            ->  Bitmap Index Scan on table_one_timestamp_idx  (cost=0.00..1040.00 rows=79941 width=0)
                  Index Cond: ("timestamp" > (now() - '30 days'::interval))
            ->  Bitmap Index Scan on fki_table_three_client_id  (cost=0.00..1406.05 rows=107978 width=0)
                  Index Cond: (client_id > 0)

Veya EXPLAIN ANALYZEbasit, devasa bir tablonun çıktısında (çok az work_mem):

EXPLAIN ANALYZE SELECT * FROM aa WHERE a BETWEEN 100000 AND 200000;
Bitmap Heap Scan on aa  (cost=107.68..4818.05 rows=5000 width=4) (actual time=27.629..213.606 rows=100001 loops=1)
  Recheck Cond: ((a >= 100000) AND (a <= 200000))
  Rows Removed by Index Recheck: 758222
  Heap Blocks: exact=693 lossy=3732
  ->  Bitmap Index Scan on aai  (cost=0.00..106.43 rows=5000 width=0) (actual time=27.265..27.265 rows=100001 loops=1)
        Index Cond: ((a >= 100000) AND (a <= 200000))

Bu, endeks koşullarının bir bitmap dizin taramasından sonra ikinci kez kontrol edilmesi gerektiği anlamına mı geliyor? Çıktıdan
başka ne öğrenebiliriz EXPLAIN?

Yanıtlar:


17

As @Chris başvurulan soru üzerine doğru yorumladı :

küçük bir araştırma, yeniden kontrol koşulunun her zaman yazdırıldığını gösterir EXPLAIN, ancak aslında sadece work_membitmap'in kaybolacağı kadar küçük olduğunda gerçekleştirilir . Düşünceler? http://www.postgresql.org/message-id/464F3C5D.2000700@enterprisedb.com

Bu doğru ve çekirdek geliştirici Heikki Linnakangas birinci sınıf bir kaynak olsa da, yazı 2007'ye kadar uzanıyor (Postgres 8.2). İşte Michael Paquier'in Postgres 9.4 için ayrıntılı açıklaması olanEXPLAIN ANALYZE ve daha fazla bilgi ile çıktısının geliştirildiği bir blog yazısı .

Recheck Cond:Çizgidir hep bitmap indeks taramalar için orada. Temel çıktı EXPLAINbize daha fazla anlatmayacağım. Sorudaki EXPLAIN ANALYZEikinci alıntıda görüldüğü gibi ek bilgi alıyoruz :

Heap Blocks: exact=693 lossy=3732

Toplam 4425 veri sayfasından (bloklar), 693 tam olarak ( saklanan işaretçiler dahil) kapları saklarken, diğer 3732 sayfa bitmap'te kayıplıydı (sadece veri sayfası). Bu work_mem, dizin taramasından oluşturulan tüm bitmap'i tam olarak (kayıpsız) depolayacak kadar büyük olmadığında olur .

Dizin koşulu, kayıp paylaşımdaki sayfalar için yeniden kontrol edilmelidir, çünkü bitmap, sayfadaki tam tuplleri değil, yalnızca hangi sayfaların getirileceğini hatırlar. Sayfadaki tüm grupların mutlaka dizin koşullarını geçmesi gerekmez, gerçekten durumu yeniden kontrol etmek gerekir .

Bu, yeni eklemenin tartışıldığı pgsql bilgisayar korsanları konusudur . Yazar Etsuro Fujita, kayıpwork_mem bitmap girişlerinden ve sonraki koşul yeniden kontrollerinden kaçınmak için minimumun nasıl hesaplanacağına dair bir formül sunar . Hesaplama, birden çok bitmap taraması olan karmaşık durumlar için güvenilir değildir, bu nedenle gerçek sayıları çıktılamak için kullanılmamıştır EXPLAIN. Yine de basit vakalar için bir tahmin görevi görebilir.

Ek satır BUFFERS:

Buna ek olarak, BUFFERSseçenekle çalışırken : EXPLAIN (ANALYZE, BUFFERS) ...şunun gibi başka bir satır eklenir:

Buffers: shared hit=279 read=79

Bu, temel tablonun (ve dizinin) önbellekten ( shared hit=279) ne kadarının okunduğunu ve diskten ( read=79) ne kadar alınmasının gerektiğini gösterir . Sorguyu tekrarlarsanız, "okuma" bölümü genellikle çok büyük olmayan sorgular için kaybolur, çünkü her şey ilk çağrıdan sonra önbelleğe alınır. İlk çağrı size ne kadarının önbelleğe alındığını gösterir. Sonraki aramalar, önbelleğinizin (şu anda) ne kadar işleyebileceğini gösterir.

Daha fazla seçenek var. Seçenek hakkında kılavuz BUFFERS:

Özellikle, isabet, okuma, kirlenmiş ve yazılmış paylaşılan blokların sayısını, isabet, okuma, kirlenmiş ve yazılmış yerel blokların sayısını ve okunan ve yazılan geçici blokların sayısını ekleyin.

Okuyun, dahası var. Kaynak koddaki
çıktı seçeneklerinin listesi .


10

Erwin, bu daha önce yaptığımız yorum dizisindeki tartışmamız olduğundan, biraz daha konuşmaya karar verdim ...

Makul boyutlu bir tablodan çok basit bir sorgu var. Tipik olarak yeterliyim work_mem, ama bu durumda komutları kullandım

SET work_mem = 64;

çok küçük work_memve

SET work_mem = default;

Benim ayarlamak için work_memSorgumda yeterince büyük olmasının arkasını.

EXPLAIN ve Yeniden Kontrol Durumu

Yani, sadece benim sorguyu çalıştıran EXPLAINolarak

EXPLAIN 
SELECT * FROM olap.reading_facts
WHERE meter < 20;

Hem düşük hem de yüksek sonuçlar elde ettim work_mem:

Düşük work_mem

Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32)
  Recheck Cond: (meter < 20)
  ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0)
        Index Cond: (meter < 20)

Yüksek work_mem

Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32)
  Recheck Cond: (meter < 20)
  ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0)
        Index Cond: (meter < 20)

Uzun lafın kısası, EXPLAIN sadece, beklendiği gibi, sorgu planı bir Recheck koşulunun mümkün olduğunu gösterir, ancak aslında hesaplanıp hesaplanmayacağını bilemeyiz.

AÇIKLAMA ANALİZİ ve Tekrar Kontrol Durumu

ANALYZESorguya dahil ettiğimizde , sonuçlar bize bilmemiz gerekenler hakkında daha fazla bilgi verir.

Düşük work_mem

Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32) (actual time=3.130..13.946 rows=51840 loops=1)
  Recheck Cond: (meter < 20)
  Rows Removed by Index Recheck: 86727
  Heap Blocks: exact=598 lossy=836
  ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0) (actual time=3.066..3.066 rows=51840 loops=1)
        Index Cond: (meter < 20)

Yüksek work_mem

Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32) (actual time=2.647..7.247 rows=51840 loops=1)
  Recheck Cond: (meter < 20)
  Heap Blocks: exact=1434
  ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0) (actual time=2.496..2.496 rows=51840 loops=1)
        Index Cond: (meter < 20)

Yine, beklendiği gibi, ANALYZEbize dahil edilmesi çok önemli bazı bilgileri ortaya koymaktadır. Düşük work_memdurumda, dizin yeniden denetimi tarafından kaldırılan satırlar olduğunu ve lossyyığın bloklarımız olduğunu görüyoruz .

Sonuç? (veya eksikliği)

Ne yazık ki, EXPLAINkendi başına bir dizin yeniden denetiminin gerçekten gerekli olup olmayacağını bilmek yeterli görünmüyor , çünkü bazı satır kimlikleri bitmap yığın taraması sırasında sayfaları korumak lehine bırakılıyor.

Kullanımı EXPLAIN ANALYZE, orta uzunluktaki sorgularla ilgili sorunları teşhis etmek için iyidir, ancak bir sorgunun tamamlanması çok uzun zaman EXPLAIN ANALYZEalıyorsa, bitmap dizininizin yetersiz work_memolması nedeniyle kayıplıya dönüştüğünü keşfetmek hala zor bir kısıtlamadır. Keşke EXPLAINbu oluşumun tablo istatistiklerinden tahmin edilmesinin bir yolu olsaydı .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.