จากปัญหาที่พบเจอในระบบงานคือ ความช้าของระบบงาน
จากการ 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