PostgreSQL คืออะไรอธิบายบอกฉันได้อย่างแน่นอน


116

ผลลัพธ์อธิบายของ MySQL ค่อนข้างตรงไปตรงมา PostgreSQL มีความซับซ้อนกว่าเล็กน้อย ฉันไม่สามารถหาแหล่งข้อมูลที่ดีที่อธิบายได้เช่นกัน

คุณสามารถอธิบายสิ่งที่อธิบายได้อย่างชัดเจนหรืออย่างน้อยก็ชี้ให้ฉันเห็นทิศทางของทรัพยากรที่ดี

คำตอบ:


50

Explaining_EXPLAIN.pdfก็ช่วยได้เช่นกัน


65
ฉันรู้สึกประหลาดใจว่าทำไมผู้คนถึงคิดว่าชั้นสไลด์ทำเอกสารทางเทคนิคที่ดี วิดีโอการพูดคุยอาจเป็นประโยชน์ แต่ความหนาแน่นของข้อมูลของชุดสไลด์นั้นใกล้เคียงกับศูนย์มาก ในหกสไลด์แรก (1/5 ของทั้งหมด) มีเนื้อหาทางเทคนิค 1 ประโยค: "• EXPLAIN ใช้ได้กับ DML ใด ๆ ไม่ใช่แค่ SELECT (เช่น UPDATE, DELETE และ INSERT)" ความเข้าใจผิดที่ยิ่งใหญ่ที่สุดของฉันคือความหมายของเวลา "เริ่มต้น" และไม่มีคำอธิบายใด ๆ ในประมาณ 30 สไลด์เหล่านี้
Mark E. Haase

80

ส่วนที่ฉันมักจะสับสนคือต้นทุนเริ่มต้นเทียบกับต้นทุนทั้งหมด ฉัน Google ทุกครั้งที่ฉันลืมมันซึ่งทำให้ฉันกลับมาที่นี่ซึ่งไม่ได้อธิบายความแตกต่างนั่นคือเหตุผลที่ฉันเขียนคำตอบนี้ นี่คือสิ่งที่ผมได้รวบรวมจากPostgres EXPLAINเอกสาร , อธิบายที่ผมเข้าใจ

นี่คือตัวอย่างจากแอปพลิเคชันที่จัดการฟอรัม:

EXPLAIN SELECT * FROM post LIMIT 50;

Limit  (cost=0.00..3.39 rows=50 width=422)
  ->  Seq Scan on post  (cost=0.00..15629.12 rows=230412 width=422)

นี่คือคำอธิบายแบบกราฟิกจาก PgAdmin:

คำอธิบายแบบกราฟิกของแบบสอบถามแรก

(เมื่อคุณใช้ PgAdmin คุณสามารถชี้เมาส์ไปที่ส่วนประกอบเพื่ออ่านรายละเอียดค่าใช้จ่าย)

ค่าใช้จ่ายจะแสดงเป็นอันดับหนึ่งเช่นค่าใช้จ่ายของการLIMITเป็นcost=0.00..3.39และค่าใช้จ่ายของการสแกนตามลำดับคือpost cost=0.00..15629.12จำนวนครั้งแรกใน tuple เป็นค่าใช้จ่ายในการเริ่มต้นและจำนวนที่สองคือค่าใช้จ่ายทั้งหมด เนื่องจากฉันใช้EXPLAINและไม่ได้EXPLAIN ANALYZEค่าใช้จ่ายเหล่านี้เป็นค่าประมาณไม่ใช่มาตรการจริง

  • ต้นทุนการเริ่มต้นเป็นแนวคิดที่ยุ่งยาก มันไม่เพียง แต่เป็นตัวแทนของระยะเวลาก่อนว่าองค์ประกอบที่จะเริ่มต้น เพราะมันหมายถึงปริมาณของเวลาระหว่างเมื่อเริ่มต้นองค์ประกอบการดำเนินการ (อ่านข้อมูล) และเมื่อองค์ประกอบที่จะแสดงแถวแรกของ
  • ต้นทุนรวมคือเวลาดำเนินการทั้งหมดของส่วนประกอบตั้งแต่เมื่อเริ่มอ่านข้อมูลไปจนถึงเมื่อเขียนผลลัพธ์เสร็จสิ้น

ในฐานะที่เป็นภาวะแทรกซ้อนต้นทุนของโหนด "พาเรนต์" แต่ละโหนดจะรวมค่าใช้จ่ายของโหนดลูกด้วย ในการแสดงข้อความต้นไม้จะแสดงด้วยการเยื้องเช่นLIMITเป็นโหนดแม่และSeq Scanเป็นลูกของมัน ในการแสดง PgAdmin ลูกศรจะชี้จากลูกไปยังแม่ - ทิศทางของการไหลของข้อมูล - ซึ่งอาจสวนทางกันได้หากคุณคุ้นเคยกับทฤษฎีกราฟ

เอกสารกล่าวว่าค่าใช้จ่ายรวมทั้งหมดโหนดลูก แต่แจ้งให้ทราบว่าค่าใช้จ่ายรวมของ บริษัท ใหญ่มีขนาดเล็กกว่าค่าใช้จ่ายทั้งหมดของเด็กมัน3.39 15629.12ไม่รวมต้นทุนทั้งหมดเนื่องจากส่วนประกอบเช่นLIMITไม่จำเป็นต้องประมวลผลอินพุตทั้งหมด ดูEXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2;ตัวอย่างในPostgresEXPLAINเอกสาร

ในตัวอย่างด้านบนเวลาเริ่มต้นเป็นศูนย์สำหรับทั้งสององค์ประกอบเนื่องจากองค์ประกอบทั้งสองไม่จำเป็นต้องดำเนินการประมวลผลใด ๆ ก่อนที่จะเริ่มเขียนแถว: การสแกนตามลำดับจะอ่านแถวแรกของตารางและส่งออกมา LIMITอ่านแถวแรกและจากนั้นก็ปล่อยออกมา

เมื่อใดที่คอมโพเนนต์จะต้องทำการประมวลผลจำนวนมากก่อนจึงจะเริ่มส่งออกแถวใด ๆ ได้ มีหลายสาเหตุที่เป็นไปได้ แต่ลองดูตัวอย่างที่ชัดเจน นี่คือข้อความค้นหาเดียวกันจากก่อนหน้านี้ แต่ตอนนี้มีORDER BYอนุประโยค:

EXPLAIN SELECT * FROM post ORDER BY body LIMIT 50;

Limit  (cost=23283.24..23283.37 rows=50 width=422)
  ->  Sort  (cost=23283.24..23859.27 rows=230412 width=422)
        Sort Key: body
        ->  Seq Scan on post  (cost=0.00..15629.12 rows=230412 width=422)

และแบบกราฟิก:

คำอธิบายแบบกราฟิกของแบบสอบถามที่สอง

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

สังเกตว่าเวลาLIMIT 23283.24เริ่มต้นของการจัดเรียงจะเท่ากับเวลาเริ่มต้นของการจัดเรียง นี่ไม่ใช่เพราะLIMITตัวเองมีเวลาเริ่มต้นสูง จริงๆแล้วมันไม่มีเวลาเริ่มต้นด้วยตัวเอง แต่EXPLAINจะรวมค่าใช้จ่ายลูกทั้งหมดสำหรับผู้ปกครองแต่ละคนดังนั้นLIMITเวลาเริ่มต้นจึงรวมเวลาเริ่มต้นรวมของลูกด้วย

การรวบรวมต้นทุนนี้อาจทำให้ยากที่จะเข้าใจต้นทุนการดำเนินการของแต่ละองค์ประกอบ ตัวอย่างเช่นเราLIMITมีเวลาเริ่มต้นเป็นศูนย์ แต่ไม่ชัดเจนในตอนแรก ด้วยเหตุนี้คนอื่น ๆ หลายคนจึงเชื่อมโยงกับExplanation.depesz.comซึ่งเป็นเครื่องมือที่สร้างขึ้นโดย Hubert Lubaczewski (aka depesz) ซึ่งช่วยให้เข้าใจEXPLAINโดยการหักต้นทุนเด็กออกจากต้นทุนของผู้ปกครอง เขากล่าวถึงความซับซ้อนอื่น ๆ ในบล็อกโพสต์สั้น ๆเกี่ยวกับเครื่องมือของเขา


4
ขอบคุณสำหรับสิ่งนี้. ฉันต้องการเพิ่ม Visualizer อธิบายที่ทำงานได้ดียิ่งขึ้นในการแสดงผลลัพธ์ (imo) tatiyants.com/pev
Jonathan Porter

คำตอบที่ดี และความคิดเห็นของคุณที่ว่าค่าเริ่มต้นรวมเวลาในการส่งคืนแถวแรกช่วยให้ฉันเข้าใจว่าเหตุใดค่าเริ่มต้นสำหรับ Sort จึงไม่ใช่แค่ 15629.12
Joel Wigton

43

มันดำเนินการจากส่วนใหญ่เยื้องไปยังเยื้องน้อยที่สุดและฉันเชื่อว่าจากด้านล่างของแผนไปด้านบน (ดังนั้นหากมีการเยื้องสองส่วนส่วนที่อยู่ไกลออกไปจากหน้าจะดำเนินการก่อนจากนั้นเมื่อพบกับการดำเนินการอื่น ๆ กฎที่รวมเข้าด้วยกันจะดำเนินการ)

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

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

explain analyze
select a.attributeid, a.attributevalue, b.productid
from orderitemattribute a, orderitem b
where a.orderid = b.orderid
and a.attributeid = 'display-album'
and b.productid = 'ModernBook';

------------------------------------------------------------------------------------------------------------------------------------------------------------

 Merge Join  (cost=125379.14..125775.12 rows=3311 width=29) (actual time=841.478..841.478 rows=0 loops=1)
   Merge Cond: (a.orderid = b.orderid)
   ->  Sort  (cost=109737.32..109881.89 rows=57828 width=23) (actual time=736.163..774.475 rows=16815 loops=1)
         Sort Key: a.orderid
         Sort Method:  quicksort  Memory: 1695kB
         ->  Bitmap Heap Scan on orderitemattribute a  (cost=1286.88..105163.27 rows=57828 width=23) (actual time=41.536..612.731 rows=16815 loops=1)
               Recheck Cond: ((attributeid)::text = 'display-album'::text)
               ->  Bitmap Index Scan on (cost=0.00..1272.43 rows=57828 width=0) (actual time=25.033..25.033 rows=16815 loops=1)
                     Index Cond: ((attributeid)::text = 'display-album'::text)
   ->  Sort  (cost=15641.81..15678.73 rows=14769 width=14) (actual time=14.471..16.898 rows=1109 loops=1)
         Sort Key: b.orderid
         Sort Method:  quicksort  Memory: 76kB
         ->  Bitmap Heap Scan on orderitem b  (cost=310.96..14619.03 rows=14769 width=14) (actual time=1.865..8.480 rows=1114 loops=1)
               Recheck Cond: ((productid)::text = 'ModernBook'::text)
               ->  Bitmap Index Scan on id_orderitem_productid  (cost=0.00..307.27 rows=14769 width=0) (actual time=1.431..1.431 rows=1114 loops=1)
                     Index Cond: ((productid)::text = 'ModernBook'::text)
 Total runtime: 842.134 ms
(17 rows)

ลองอ่านด้วยตัวคุณเองและดูว่าเข้าท่าไหม

สิ่งที่ฉันอ่านคือฐานข้อมูลจะสแกนid_orderitem_productidดัชนีก่อนโดยใช้เพื่อค้นหาแถวที่ต้องการจากorderitemนั้นจัดเรียงชุดข้อมูลนั้นโดยใช้ Quicksort (การจัดเรียงที่ใช้จะเปลี่ยนไปหากข้อมูลไม่พอดีกับ RAM) จากนั้นจึงตั้งค่าไว้ข้างๆ

จากนั้นจะสแกนorditematt_attributeid_idxเพื่อค้นหาแถวที่ต้องการจากorderitemattributeนั้นจัดเรียงชุดข้อมูลนั้นโดยใช้ Quicksort

จากนั้นจะใช้ชุดข้อมูลทั้งสองชุดและรวมเข้าด้วยกัน (การรวมการผสานคือการดำเนินการ "การบีบอัด" แบบหนึ่งที่จะนำชุดข้อมูลที่เรียงลำดับสองชุดไปพร้อมกันโดยปล่อยแถวที่รวมเข้าด้วยกันเมื่อตรงกัน)

อย่างที่ฉันบอกคุณทำงานผ่านแผนส่วนในไปยังส่วนนอกจากล่างขึ้นบน


22

นอกจากนี้ยังมีเครื่องมือช่วยเหลือออนไลน์Depeszซึ่งจะเน้นว่าส่วนที่มีราคาแพงของผลการวิเคราะห์อยู่ที่ใด

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


20
explore-analyze.info ดูเหมือนจะไม่ทำงาน แต่ฉันเห็นพ้องกันว่า อธิบาย.depesz.comมีประโยชน์มาก
benvolioT

13

PgAdminจะแสดงแผนอธิบายแบบกราฟิกให้คุณเห็น การสลับไปมาระหว่างทั้งสองจะช่วยให้คุณเข้าใจความหมายของการแสดงข้อความได้อย่างแท้จริง อย่างไรก็ตามหากคุณแค่อยากรู้ว่าต้องทำอะไรคุณอาจสามารถใช้ GUI ได้ตลอดเวลา



0

หากคุณติดตั้ง pgadmin จะมีปุ่มอธิบายที่ให้เอาต์พุตข้อความวาดไดอะแกรมของสิ่งที่เกิดขึ้นแสดงตัวกรองประเภทและการรวมชุดย่อยที่ฉันคิดว่ามีประโยชน์มากในการดูว่าเกิดอะไรขึ้น

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