อ่านแผน EXPLAIN
ตีความประเภทการสแกน วิธีการเชื่อมตาราง และค่าประมาณต้นทุนในแผนคำสั่งค้นหา
อ่านแผน EXPLAIN เป็นบทเรียน Coding Interview Prep ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Coding Interview Prep และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Coding Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดผู้สัมภาษณ์จึงถามเกี่ยวกับ EXPLAIN
เมื่อเข้าสู่รอบสัมภาษณ์ระดับอาวุโส ผู้สัมภาษณ์จะเลิกถามว่า เขียนคำสั่งสอบถาม และเริ่มถามว่า เหตุใดคำสั่งสอบถามนี้จึงช้า เครื่องมือที่ใช้ตอบคำถามนี้คือ EXPLAIN
EXPLAIN แสดง แผนการดำเนินการ ของฐานข้อมูล ซึ่งเป็นกลยุทธ์ทีละขั้นตอนที่ตัววางแผนเลือกใช้เพื่อดำเนินการ SQL ของคุณ แผนนี้เปิดเผยว่ามีการสแกนตารางใดบ้าง เชื่อมตารางตามลำดับใด และแต่ละขั้นตอนใช้ทรัพยากรมากเพียงใดโดยประมาณ
ความสามารถในการอ่านแผนได้แสดงว่าคุณเข้าใจกลไกของฐานข้อมูล ไม่ใช่เพียงไวยากรณ์ นี่คือสิ่งที่ผู้สัมภาษณ์ใช้แยกผู้สมัครระดับกลางออกจากระดับอาวุโส
EXPLAIN เทียบกับ EXPLAIN ANALYZE
มีสองรูปแบบ และผู้สัมภาษณ์มักให้ความสำคัญกับความแตกต่างนี้
- EXPLAIN แสดงแผนที่ตัววางแผน คาดการณ์ โดยไม่ดำเนินการคำสั่งสอบถาม รวดเร็วและปลอดภัย
- EXPLAIN ANALYZE จะ ดำเนินการคำสั่งสอบถามจริง และรายงานจำนวนแถวกับเวลาที่ใช้ จริง ควบคู่กับค่าคาดการณ์
จุดสำคัญคือการเปรียบเทียบจำนวนแถวที่คาดการณ์กับจำนวนแถวจริง หากแตกต่างกันมาก แสดงว่าตัววางแผนมีสถิติที่ไม่ดีและมีแนวโน้มเลือกแนวทางที่ไม่เหมาะสม
ข้อควรระวัง: EXPLAIN ANALYZE จะดำเนินการคำสั่งสอบถามจริง ดังนั้นจะดำเนินการ INSERT หรือ UPDATE ด้วย เว้นแต่จะครอบไว้ในธุรกรรมที่ย้อนกลับแล้ว
EXPLAIN ANALYZE
SELECT * FROM orders WHERE customer_id = 42;วิธีอ่านต้นไม้
แผนเป็น ต้นไม้ ไม่ใช่รายการ โหนดที่เยื้องเข้ามามากที่สุดคือ โหนดใบ ซึ่งทำงานก่อน ผลลัพธ์จะไหลขึ้นไปยังรากที่สร้างผลลัพธ์สุดท้าย
ให้อ่านจากด้านในออกด้านนอก: ค้นหาโหนดที่อยู่ลึกที่สุด เพราะจุดนั้นคือจุดเริ่มต้นของการดำเนินการ โหนดแม่แต่ละโหนดจะรับแถวที่โหนดลูกส่งออกมา
ในการสัมภาษณ์ ให้อธิบายตามลำดับนั้น: ขั้นแรก เราสแกนตารางนี้ แถวเหล่านั้นส่งต่อไปยังการเชื่อมข้อมูลนี้ การเชื่อมข้อมูลส่งต่อไปยังการเรียงลำดับ และการเรียงลำดับส่งต่อไปยังขีดจำกัด การอธิบายจากล่างขึ้นบนเช่นนี้คือสิ่งที่ผู้สัมภาษณ์ต้องการฟัง
โครงสร้างของโหนดแผน
โหนดทุกโหนดในแผนของ Postgres มีตัวเลขสำคัญชุดเดียวกัน:
- ต้นทุน=0.00..35.50 ต้นทุนเริ่มต้น..ต้นทุนรวมในหน่วยของตัววางแผนที่กำหนดขึ้นเอง
- แถว=1000 จำนวนแถวที่สร้างขึ้นโดยประมาณ
- ความกว้าง=64 ขนาดแถวเฉลี่ยโดยประมาณเป็นไบต์
ต้นทุนแรกคือต้นทุนเริ่มต้น (งานที่ทำก่อนแถวแรกจะปรากฏ เช่น การสร้างตารางแฮช) ต้นทุนที่สองคือต้นทุนรวมสำหรับส่งคืนแถวทั้งหมด ต้นทุนรวมที่สูงกว่าคือการคาดการณ์ของตัววางแผนเกี่ยวกับค่าใช้จ่ายสัมพัทธ์
Seq Scan on orders (cost=0.00..35.50 rows=1000 width=64)ตัวอย่างที่ทำให้ดู
ลองพิจารณาคำสั่งสอบถามที่มีตัวกรองอย่างง่าย แผนด้านล่างนี้บอกเรื่องราวได้ในบรรทัดเดียว
นี่คือการสแกนตามลำดับ (อ่านทั้งตาราง) บน orders โดยใช้ตัวกรอง status = 'shipped' ตัววางแผนประมาณการว่ามีแถวที่ตรงกัน 1,000 แถว
หาก orders มี 10 ล้านแถวและมีเพียง 1,000 แถวที่ตรงกัน ผู้สัมภาษณ์คาดหวังให้คุณตอบว่า: การสแกนตามลำดับในกรณีนี้สิ้นเปลือง ดัชนีบนสถานะ (หรือคอลัมน์ที่เลือกเฉพาะเจาะจงได้มากกว่า) จะช่วยให้เราไม่ต้องอ่านทั้งตาราง
EXPLAIN SELECT * FROM orders WHERE status = 'shipped';
Seq Scan on orders (cost=0.00..18334.00 rows=1000 width=64)
Filter: (status = 'shipped'::text)แถวโดยประมาณเทียบกับแถวจริง
เมื่อใช้ EXPLAIN ANALYZE คุณจะได้ตัวเลขจริงในวงเล็บด้วย
ดูตัวอย่างนี้ ตัววางแผนประมาณการไว้ 1,000 แถว แต่ได้จริงถึง 480,000 แถว นั่นคือการประเมินต่ำกว่าจริง 480 เท่า ตัววางแผนเลือกกลยุทธ์โดยสมมติว่ามีแถวจำนวนน้อย ดังนั้นตัวเลือกของมันจึงน่าจะไม่เหมาะกับข้อมูลจริง
ในการสัมภาษณ์ ช่องว่างนี้คือข้อวินิจฉัยหลักที่คุณควรกล่าวถึง: สถิติไม่เป็นปัจจุบัน ให้เรียกใช้ ANALYZE กับตาราง แล้วตัววางแผนน่าจะเลือกแผนที่ดีกว่า
Seq Scan on orders
(cost=0.00..18334.00 rows=1000 width=64)
(actual time=0.02..210.4 rows=480000 loops=1)ความหมายของจำนวนรอบ=N
ค่าจำนวนรอบสำคัญกว่าที่ผู้สมัครส่วนใหญ่คาดไว้ ค่านี้คือจำนวนครั้งที่โหนดถูกดำเนินการ
ค่านี้ปรากฏที่ด้านในของการเชื่อมแบบลูปซ้อน โดยโหนดด้านในจะทำงานหนึ่งครั้งต่อแถวด้านนอก หาก loops=480000 ขั้นตอนด้านในนั้นถูกดำเนินการ 480,000 ครั้ง
ข้อสำคัญคือ เวลาและจำนวนแถวที่แสดงเป็นต่อรอบ หากต้องการยอดรวมจริง ให้คูณค่าต่อรอบด้วย loops โหนดที่ดูเหมือนมีค่าใช้จ่ายเพียง 0.004 มิลลิวินาทีต่อรอบ จะกลายเป็นเกือบ 2 วินาทีเมื่อมี 480,000 รอบ
Index Scan using idx_cust on orders
(actual time=0.003..0.004 rows=1 loops=480000)ต้นทุนเป็นค่าที่สัมพันธ์กัน ไม่ใช่มิลลิวินาที
ข้อผิดพลาดที่พบบ่อยคือ ผู้สมัครเห็น cost=18334 แล้วบอกว่า ใช้เวลา 18 วินาที ซึ่งไม่ถูกต้อง
ต้นทุนอยู่ในหน่วยของตัววางแผนที่กำหนดขึ้นเอง โดยปรับเทียบให้การอ่านหน้าตามลำดับหนึ่งหน้าเท่ากับ 1.0 ค่านี้มีความหมายเฉพาะเมื่อใช้เปรียบเทียบแผนต่าง ๆ เข้าด้วยกัน ไม่ใช่ค่าที่บอกเวลาจริงตามนาฬิกา
หากต้องการเวลาจริง คุณต้องใช้ EXPLAIN ANALYZE และค่าของ actual time ซึ่งวัดเป็นมิลลิวินาที พูดเรื่องนี้ให้ชัดเจนในการสัมภาษณ์ เพราะแสดงว่าคุณเข้าใจตัวชี้วัดนี้จริง
การอ่านแผนการเชื่อม
นี่คือแผนที่ใช้สองตาราง ให้อ่านจากล่างขึ้นบน
การสแกนสองรายการแรกจะรวบรวมแถวจาก orders และ customers แล้วส่งต่อให้การเชื่อมแบบแฮช: ฝั่งหนึ่งจะถูกทำแฮช ส่วนอีกฝั่งจะใช้ค้นหาในแฮช จากนั้นผลลัพธ์ของการเชื่อมจะถูกส่งต่อไปยังผลลัพธ์สุดท้าย
สังเกตว่าการเยื้องแสดงโครงสร้างอย่างไร: การสแกนทั้งสองรายการอยู่ใต้การเชื่อมแบบแฮช ผู้สัมภาษณ์ต้องการให้คุณระบุวิธีการเชื่อม (แฮชในกรณีนี้) และตารางที่ถูกทำแฮช (โดยปกติคือตารางที่เล็กกว่า)
Hash Join (cost=30.0..520.0 rows=900 width=72)
Hash Cond: (o.customer_id = c.id)
-> Seq Scan on orders o (cost=0..400 rows=10000)
-> Hash (cost=18..18 rows=500)
-> Seq Scan on customers c (cost=0..18 rows=500)สัญญาณอันตรายที่ควรชี้ให้เห็น
ฝึกสังเกตสัญญาณเตือนเหล่านี้ในทุกแผน:
- การสแกนตามลำดับบนตารางขนาดใหญ่มากที่มีตัวกรองเลือกเฉพาะเจาะจง ดัชนีอาจช่วยได้
- แถวโดยประมาณห่างจากแถวจริงมาก สถิติไม่เป็นปัจจุบัน
- การเชื่อมแบบลูปซ้อนที่มีจำนวนรอบสูงบนตารางใหญ่ มักหมายถึงไม่มีดัชนีบนคีย์การเชื่อมด้านใน
- การเรียงลำดับหรือการแฮชเขียนลงดิสก์ (แสดงเป็นการใช้งาน
Disk) ค่าwork_memเล็กเกินไป - แถวที่ถูกนำออกโดยตัวกรองมีจำนวนสูงมาก หมายความว่าคุณอ่านแล้วทิ้งตารางส่วนใหญ่ไป
รูปแบบผลลัพธ์และ BUFFERS
แผนมีหลายรูปแบบ โดยค่าเริ่มต้นคือ TEXT ซึ่งเป็นรูปแบบที่คุณอ่านออกเสียงในการสัมภาษณ์ แต่คุณยังสามารถขอผลลัพธ์แบบมีโครงสร้างได้
EXPLAIN (FORMAT JSON) หรือ FORMAT YAML จะสร้างแผนที่เครื่องอ่านได้ ซึ่งเครื่องมือและแดชบอร์ดสามารถนำไปวิเคราะห์ได้ โดยทั่วไปคุณแทบไม่ต้องอ่านรูปแบบเหล่านี้ด้วยตนเอง แต่การรู้ว่ามีรูปแบบเหล่านี้อยู่ก็แสดงความเข้าใจในระดับผู้มีประสบการณ์สูงได้ดี
เพิ่มตัวเลือกไว้ในวงเล็บ: EXPLAIN (ANALYZE, BUFFERS) ตัวเลือก BUFFERS จะรายงานการพบข้อมูลในแคชเทียบกับการอ่านจากดิสก์ ซึ่งมีประโยชน์อย่างมากในการวินิจฉัยคำสั่งสอบถามที่ติดข้อจำกัดด้านอินพุต/เอาต์พุต
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM orders WHERE customer_id = 42;ตรวจสอบอย่างรวดเร็ว
ผู้สัมภาษณ์แสดงโหนด EXPLAIN ANALYZE ที่มี rows=1000 ในส่วนต้นทุน แต่มี actual ... rows=480000 การวินิจฉัยที่เป็นไปได้มากที่สุดคืออะไร?
ทบทวน
ตอนนี้คุณอ่านแผนได้เหมือนผู้มีประสบการณ์สูงแล้ว:
EXPLAINใช้ประมาณการ ส่วนEXPLAIN ANALYZEใช้ดำเนินการและวัดผล- อ่านแผนผังจากล่างขึ้นบน ใบของแผนผังจะทำงานก่อน และรากจะสร้างผลลัพธ์
- แต่ละโหนดแสดงต้นทุน (หน่วยสัมพัทธ์) จำนวนแถว และความกว้าง ส่วน
actual timeคือเวลาจริงในหน่วยมิลลิวินาที loopsใช้คูณค่าต่อรอบ ให้ระวังการเชื่อมแบบลูปซ้อน- ช่องว่างระหว่างจำนวนแถวโดยประมาณกับจำนวนแถวจริงคือสัญญาณวินิจฉัยที่สำคัญที่สุด
บรรยายแผนออกเสียงและชี้ให้เห็นสัญญาณอันตราย นี่คือพฤติกรรมที่ช่วยให้โดดเด่นในการสัมภาษณ์
คำถามที่พบบ่อย
บทเรียน “อ่านแผน EXPLAIN” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “อ่านแผน EXPLAIN” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Coding Interview Prep ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Coding Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “อ่านแผน EXPLAIN”
ตีความประเภทการสแกน วิธีการเชื่อมตาราง และค่าประมาณต้นทุนในแผนคำสั่งค้นหา คุณปฏิบัติ Coding Interview Prep ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Coding Interview Prep หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Coding Interview Prep บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “อ่านแผน EXPLAIN” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Coding Interview Prep นี้ได้ไหม
ได้ บทเรียน Coding Interview Prep ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- อ่านแผน EXPLAIN
- การสแกนตามลำดับเทียบกับการสแกนดัชนีและการสแกนเฉพาะดัชนี
- อัลกอริทึมการเชื่อมตาราง: ลูปซ้อน แฮช และผสาน
- ค้นหาและแก้ไขคำสั่งค้นหาที่ช้า