GORAGOD.com

การเร่งความเร็วของ LEFT JOIN และ ลำดับของฟิลด์ที่ใช้เป็น Index

LEFT JOIN ปกติแล้วจะให้ผลลัท์ที่ช้ากว่า INNER JOIN อยู่แล้วถึงแม้จะมีการทำ Index ข้อมูลไว้แล้วก็ตาม โดยเฉพาะในกรณีที่ Index ประกอบด้วยข้อมูลจากหลายฟิลด์ อาจทำให้การ JOIN ไม่สามารถใช้ความสามารถของ Index ได้ หากการจัดลำดับ Index ของตารางไม่ถูกต้อง
SELECT C.`id`,C.`contract_no`,C.`bank_id`,P.`id_card`,N.`name`,D.`phone`,L.`court_id`,L.`black_case`,L.`red_case` 
FROM `follow_gcms`.`tbl_contract` AS C 
INNER JOIN `follow_gcms`.`tbl_person_name` AS N ON N.`contract_id` = C.`id` AND N.`customer_id` = C.`customer_id` 
INNER JOIN `follow_gcms`.`tbl_person` AS P ON P.`id` = N.`person_id` AND P.`customer_id` = C.`customer_id` 
LEFT JOIN `follow_gcms`.`tbl_person_address` AS D ON D.`name_id` = N.`id` AND N.`customer_id` = C.`customer_id` 
LEFT JOIN `follow_gcms`.`tbl_lawsuit` AS L ON L.`id` = C.`lawsuit_id` AND L.`customer_id` = C.`customer_id` 
WHERE C.`customer_id` = 1

จากการรัน Query ด้านบน ด้วยข้อมูลหลักประมาณสองพันกว่ารายการ (ไม่นับข้อมูลตารางอื่นๆอีกหลายตาราง) ซึ่งผลลัพท์การ Query ที่ได้ช้ามากๆ ทั้งๆที่เบื่องต้นได้มีการทำ Index แล้วในทุกตาราง ซึ่งโดยหลักการก็พอเข้าใจได้ เนื่องจากมีการใช้ LEFT JOIN ใน Query ซึ่งคำสั่งนี้จะให้ผลลัพท์ที่ช้ากว่า INNER JOIN อยู่แล้ว (ในเคสนี้ไม่สามารถใช้ INNER JOIN ได้ เนื่องจากข้อมูลในตารางนั้นๆอาจมีหรือไม่ก็ได้)

ผมเลยทดสอบด้วยการ Explain Query ได้ผลลัพท์ดังรูปด้านล่าง จากข้อมูลที่ได้บอกว่า ตาราง D คือตารางที่ช้า เนื่องจากมีการประมวลผลทุก Record โดยไม่ได้ใช้ Index เลย

ขั้นตอนต่อมาผมไปสำรวจ Index ของตาราง D แสดงว่ามีการกำหนด Index ไว้แล้วอย่างแน่นอน ดังรูปด้านล่าง จุดสังเกตในกรณีนี้คือ custom_id ซึ่งมี Cardinality แค่เพียง 1 รายการ ซึ่งนี่เป็นสาเหตุให้การ Query ยังคงต้องไต่ไปตามข้อมูลนี้ทุกๆรายการ

เมื่อได้ข้อสรุปของปัญหามาแล้ว ก็ถึงเวลาแก้ปัญหา หลักการก็คือมีการจัดลำดับของ Index ผิด ทำให้การ Query ไม่สามารถใช้ Index ได้เต็มที่ การแก้ไขคือต้องจัดลำดับ Index ให้เอา name_id ขึ้นก่อน customer_id ผลลัพท์จากการจัดลำดับของ Index ใหม่คือเราได้ Cardinality ทั้ง name_id และ custom_id มาเรียบร้อย กลับไปสำรวจ Explain ของ Query อีกครั้ง ได้ผลลัพท์ดังรูป จากผลลัพท์จะเห็นได้ว่า ตาราง D มีการใช้ Index เรียบร้อยแล้ว ซึ่งก็ส่งผลให้ Query ที่ได้เร็วขึ้น

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