
จากปัญหาที่พบเจอในระบบงานคือ ความช้าของระบบงาน
จากการ query หรือ ดึงข้อมูลจาก database (RDBMS) มาแสดงผล และ ออก report ต่าง ๆ
ซึ่งพบเจอ query ที่เจอใน slow query log เพียบเลย
หนึ่งใน query ที่น่าสนใจ เป็นดังนี้
รวมทั้งแนวทางในการแก้ไขแบบ short term และ long term
มาเริ่มกันเลย
ตัวอย่างของ query ที่น่าสนใจ
จากที่เข้าไปดูปัญหาก็พบว่า
- เป็นการ query เพื่อกรองข้อมูลจากทั้งหมดที่มีอยู่ ทำให้ช้า และเปลือง memory มาก ๆ
- มีการใส่ index ปกติ แต่ก็ยังช้า เพราะว่าข้อมูลมีจำนวนมาก
- ไม่มีการทำ partitioning table เพื่อแยกข้อมูลตามรูปแบบของการใช้งาน
ข้อจำกัดที่ตามมาคือ ยังไม่สามารถเข้าไปแก้ไข database ใด ๆ ได้มากนัก
เช่นการ เปลี่ยน structure ของ table หรือ ไปทำ partitioning table
หรือจะไปเปลี่ยนให้ดึงข้อมูลจากช่วงเวลาไม่เกิน 1 ปี ก็ทำไม่ได้อีก !! (ไม่ให้ทำเพราะว่า ขัดแย้งกับความต้องการ)
ดังนั้นแนวทางนี้ จะเอาไว้ใช้สำหรับ long term solution ต่อไป
ดังนั้นจึงลองมาทำการ tuning sql query กันหน่อย
มาเริ่มกันเลย
ก่อนอื่นต้องรู้ก่อนว่าปัจจุบันเป็นอย่างไร ?
จากนั้นทำการแก้ไขนิดหน่อย
- สร้าง index ไว้
- โดย column a นั้นมีค่า selective ต่ำมาก ๆ จึงทำ index ให้ column a + start date + end date
- ทำ index ของ date ด้วย GiST(Generalized Search Tree)
ผลการ analyze query ซึ่ง execute time = 20.943 ms เป็นดังนี้
จาก query นั้นทำการดึงข้อมูลทั้งหมดมา filter ซึ่งไม่ดีเลย
น่าจะต้องกำหนด minimum ของ start date จะทำให้ query ดีขึ้น
ยกตัวอย่างเช่น เริ่มที่ต้นปีนี้ ซึ่งจะเร็วขึ้นมาก ๆ
แต่ว่า business requirement ไม่ต้องการแบบนี้ !!
ดังนั้นทำการดึงข้อมูลของ minimum date มาเทียบน่าจะดีกว่า !!
แต่ผลที่ได้กลับช้ากว่าเดิมมาก ๆ
ดังนั้นจึงเกิดแนวคิดว่า ถ้าเราทำ mapping index ของ a, b, c และ date ไว้ละ !!
น่าจะทำให้เวลาในการ query ดีขึ้นไหม
จึงลองสร้าง mapping table ขึ้นมาและ migrate ข้อมูล
จะได้ผลดังนี้
ผลการทำงานเร็วขึ้นมาอีก 30-50% กันเลยทีเดียว
ได้ผลดีขึ้น แถว slow query ลดน้อยลงไปอีก
โดยยังไม่ได้ไปแก้ไขโครงสร้างใด ๆ ของข้อมูล
กับไม่ได้ไปเพิ่ม index อะไรใหม่ ๆ ของ huge table เข้ามาอีก
ซึ่งมันเปลือง disk มาก ๆ
ต่อไปก็ทำการแก้ไขที่ root cause แบบ long term กันได้เลย
เรียนรู้กันต่อไป
Reference websites