“ Recheck Cond:” บรรทัดในแผนคิวรีพร้อมการสแกนดัชนีบิตแมป


21

นี่คือการแยกความคิดเห็นจากคำถามก่อนหน้า:

ใช้ PostgreSQL 9.4 มีเสมอดูเหมือนว่าจะเป็นสายหลังจากสแกนดัชนีบิตแมปในการส่งออกแผนแบบสอบถามโดยRecheck Cond:EXPLAIN

กดไลค์ในEXPLAINผลลัพธ์ของคำถามอ้างอิง:

->  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)

หรือในผลลัพธ์ของEXPLAIN ANALYZEการสร้างตารางขนาดใหญ่ที่เรียบง่าย (มีน้อยมาก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))

นั่นหมายความว่าจะต้องตรวจสอบเงื่อนไขดัชนีเป็นครั้งที่สองหลังจากการสแกนดัชนีบิตแมปหรือไม่?
เราสามารถเรียนรู้อะไรอีกจากEXPLAINผลลัพธ์

คำตอบ:


17

ในฐานะที่เป็น@ Chris แสดงความคิดเห็นได้อย่างถูกต้องเกี่ยวกับคำถามที่อ้างถึง :

การตรวจสอบเพียงเล็กน้อยดูเหมือนว่าบ่งชี้ว่าเงื่อนไขการตรวจสอบซ้ำถูกพิมพ์อยู่เสมอEXPLAINแต่จริง ๆ แล้วจะดำเนินการเฉพาะเมื่อ work_memมีขนาดเล็กพอที่บิตแมปจะสูญเสีย คิด? http://www.postgresql.org/message-id/464F3C5D.2000700@enterprisedb.com

ในขณะที่ทั้งหมดนี้เป็นจริงและผู้พัฒนาหลัก Heikki Linnakangas เป็นแหล่งข้อมูลชั้นหนึ่งวันที่โพสต์ย้อนกลับไปในปี 2007 (Postgres 8.2) นี่คือบล็อกโพสต์โดย Michael Paquier พร้อมคำอธิบายโดยละเอียดสำหรับ Postgres 9.4ซึ่งEXPLAIN ANALYZEมีการปรับปรุงผลลัพธ์ของข้อมูลเพิ่มเติม

Recheck Cond:สายเสมอมีการสแกนดัชนีบิตแมป ผลลัพธ์ของพื้นฐานEXPLAINจะไม่บอกเรามากกว่านี้ เราได้รับข้อมูลเพิ่มเติมจากEXPLAIN ANALYZEที่สามารถเห็นได้ในคำพูดที่สองในคำถาม:

Heap Blocks: exact=693 lossy=3732

จากหน้าข้อมูลทั้งหมด 4425 หน้า (บล็อก), 693 เก็บสิ่งอันดับอย่างแน่นอน (รวมถึงตัวชี้แบบ tuple) ในขณะที่หน้าอื่น ๆ 3732 หน้ามีการสูญเสีย (เพียงแค่หน้าข้อมูล) ในบิตแมป ที่เกิดขึ้นเมื่อwork_memมีขนาดไม่ใหญ่พอที่จะเก็บบิตแมปทั้งหมดที่สร้างขึ้นจากการสแกนดัชนีอย่างแน่นอน (สูญเสีย)

เงื่อนไขดัชนีต้องถูกตรวจสอบอีกครั้งสำหรับหน้าเว็บจากส่วนแบ่งการสูญเสียเนื่องจากบิตแมปจะจดจำเฉพาะหน้าที่จะดึงข้อมูลและไม่ใช่สิ่งอันดับที่แน่นอนบนหน้า สิ่งอันดับในหน้าไม่จำเป็นต้องผ่านเงื่อนไขดัชนีทั้งหมดซึ่งจำเป็นต้องใช้จริงตรวจสอบสภาพ

นี้เป็นหัวข้อเกี่ยวกับแฮกเกอร์ pgsql ที่เพิ่มใหม่ที่ถูกกล่าวถึง ผู้เขียนEtsuro Fujita จัดทำสูตรสำหรับวิธีการคำนวณขั้นต่ำwork_memเพื่อหลีกเลี่ยงรายการบิตแมปที่สูญเสียและตรวจสอบเงื่อนไขที่ตามมา การคำนวณไม่น่าเชื่อถือสำหรับกรณีที่ซับซ้อนที่มีการสแกนบิตแมปหลายรายการดังนั้นจึงไม่ได้ใช้เพื่อแสดงตัวเลขจริงจากEXPLAINการคำนวณไม่ได้เป็นที่เชื่อถือได้สำหรับกรณีที่ซับซ้อนสแกนบิตแมปหลายดังนั้นมันจึงไม่ได้ใช้ให้เป็นตัวเลขที่เกิดขึ้นจริงจากการส่งออกมันยังสามารถใช้เป็นค่าประมาณสำหรับกรณีง่าย ๆ

บรรทัดเพิ่มเติม BUFFERS:

นอกจากนี้เมื่อใช้งานด้วยBUFFERSตัวเลือก: EXPLAIN (ANALYZE, BUFFERS) ...มีการเพิ่มบรรทัดอื่นเช่น:

Buffers: shared hit=279 read=79

สิ่งนี้บ่งชี้ว่ามีการอ่านตารางพื้นฐาน (และดัชนี) จากแคช ( shared hit=279) และจำนวนเท่าใดที่ต้องดึงข้อมูลจากดิสก์ ( read=79) หากคุณทำซ้ำแบบสอบถามส่วน "อ่าน" มักจะหายไปสำหรับแบบสอบถามที่ไม่ใหญ่เกินไปเพราะทุกอย่างจะถูกเก็บไว้ตอนนี้หลังจากโทรครั้งแรก การโทรครั้งแรกจะบอกให้คุณทราบว่าถูกแคชไว้เท่าใด การโทรครั้งต่อไปจะแสดงจำนวนแคชของคุณที่สามารถจัดการได้ (ปัจจุบัน)

มีตัวเลือกเพิ่มเติม คู่มือเกี่ยวกับBUFFERSตัวเลือก:

โดยเฉพาะรวมถึงจำนวนของบล็อกที่แชร์ที่ใช้ร่วมกันอ่านสกปรกและเขียนจำนวนบล็อกในพื้นที่ที่อ่านบล็อกสกปรกและเขียนและจำนวนบล็อกชั่วคราวที่มีการอ่านและเขียน

อ่านต่อมีอีกมาก
นี่คือรายการของตัวเลือกออกในส่วนรหัสที่มา


10

เออร์วินเนื่องจากนี่คือการสนทนาของเราในหัวข้อความคิดเห็นจากก่อนหน้านี้ฉันตัดสินใจที่จะพูดต่อไปอีกเล็กน้อย ...

ฉันมีคำถามง่ายๆจากตารางที่มีขนาดเหมาะสม ฉันมักจะมีเพียงพอwork_memแต่ในกรณีนี้ฉันใช้คำสั่ง

SET work_mem = 64;

เพื่อตั้งค่าขนาดเล็กมากwork_memและ

SET work_mem = default;

เพื่อตั้งค่าให้work_memกลับมามีขนาดใหญ่พอสำหรับการสืบค้นของฉัน

อธิบายและตรวจสอบสภาพ

ดังนั้นการเรียกใช้แบบสอบถามของฉันมีเพียงEXPLAINเป็น

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

ฉันได้ผลลัพธ์ทั้งต่ำและสูงwork_mem:

ต่ำ 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)

สูง 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)

เรื่องสั้นสั้น ๆ สำหรับ EXPLAINเพียงอย่างเดียวตามที่คาดไว้แผนแบบสอบถามจะระบุว่าเงื่อนไขการตรวจสอบซ้ำเป็นไปได้ แต่เราไม่รู้ว่าจะคำนวณจริงหรือไม่

อธิบายการวิเคราะห์และตรวจสอบสภาพ

เมื่อเรารวม ANALYZEไว้ในแบบสอบถามผลลัพธ์โทรหาเราเพิ่มเติมเกี่ยวกับสิ่งที่เราต้องรู้

ต่ำ 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)

สูง 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)

อีกครั้งตามที่คาดไว้การANALYZEเปิดเผยข้อมูลบางอย่างที่สำคัญมากให้กับเรา ในwork_memกรณีที่ต่ำเราจะเห็นว่ามีการลบแถวออกโดยการตรวจสอบดัชนีและที่เรามีlossyบล็อกฮีป

สรุป? (หรือขาดมัน)

น่าเสียดายที่ดูเหมือนว่าEXPLAINตัวมันเองจะไม่เพียงพอจะรู้ว่าดัชนีการตรวจสอบใหม่นั้นมีความจำเป็นจริง ๆ หรือไม่เพราะแถวของ id id บางอันกำลังถูกทิ้งเพื่อสนับสนุนการเก็บเพจในระหว่างการสแกนบิตแม็พฮีป

การใช้EXPLAIN ANALYZEเป็นเรื่องปกติสำหรับการวินิจฉัยปัญหาที่มีการสอบถามความยาวปานกลาง แต่ในกรณีที่การสืบค้นใช้เวลานานมากในการดำเนินการให้เสร็จสมบูรณ์จากนั้นจึงEXPLAIN ANALYZEพบว่าดัชนีบิตแมปของคุณแปลงเป็นการสูญเสียเนื่องจากความไม่เพียงพอwork_memยังเป็นข้อ จำกัด ยาก ฉันหวังว่าจะมีวิธีที่จะEXPLAINประเมินความเป็นไปได้ของเหตุการณ์นี้จากสถิติตาราง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.