0Pricing
SQL Interview Prep · บทเรียน

อ่านแผน EXPLAIN

ตีความประเภทการสแกน วิธีการเชื่อมตาราง และค่าประมาณต้นทุนในแผนคำสั่งค้นหา

อ่านแผน EXPLAIN เป็นบทเรียน SQL Interview Prep ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน SQL Interview Prep และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส SQL 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) และปลดล็อคส่วนที่เหลือของคอร์ส SQL Interview Prep ให้อัปเกรดเป็น CoddyKit PRO คอร์ส SQL Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “อ่านแผน EXPLAIN”

ตีความประเภทการสแกน วิธีการเชื่อมตาราง และค่าประมาณต้นทุนในแผนคำสั่งค้นหา คุณปฏิบัติ SQL Interview Prep ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน SQL Interview Prep หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน SQL Interview Prep บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “อ่านแผน EXPLAIN” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน SQL Interview Prep นี้ได้ไหม

ได้ บทเรียน SQL Interview Prep ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. อ่านแผน EXPLAIN
  2. การสแกนตามลำดับเทียบกับการสแกนดัชนีและการสแกนเฉพาะดัชนี
  3. อัลกอริทึมการเชื่อมตาราง: ลูปซ้อน แฮช และผสาน
  4. ค้นหาและแก้ไขคำสั่งค้นหาที่ช้า
← กลับไปที่ SQL Interview Prep