Database
น้องๆ เคยเจอไหม? เขียน SQL query ไป ปรากฏว่า...รอชาติหน้าตอนบ่ายสามโมงก็ยังไม่เสร็จ! นั่นแหละครับ สาเหตุหลักๆ มักจะมาจากการที่เราไม่ได้ optimize query ให้ดีพอ ซึ่ง Sql Optimization Query Tuning Guide เนี่ย ก็คือคู่มือ (ที่พี่กำลังจะเล่าให้ฟังนี่แหละ) ที่จะช่วยให้น้องๆ เขียน SQL ได้เร็ว แรง ทะลุนรก แบบไม่ต้องเสียเวลาไปกับการนั่งรอ
ทำไมมันถึงสำคัญน่ะเหรอ? สมัยพี่ทำร้านเน็ต SiamCafe.net น่ะ (ตั้งแต่ปี 1997 โน่น!) ฐานข้อมูลลูกค้า ข้อมูลเกม ข้อมูลการใช้งาน มันเยอะมากๆ ถ้า query ช้า ลูกค้าหงุดหงิด ร้านก็เจ๊ง! (ไม่ได้ขนาดนั้นหรอก แต่เสียลูกค้าแน่ๆ) ดังนั้น การ optimize query มันสำคัญต่อ performance ของ application เราโดยรวมเลยนะเออ
ก่อนจะไปลงมือ optimize query กัน พี่ขอปูพื้นฐานนิดนึงนะ จะได้เข้าใจตรงกัน
ลองนึกภาพว่าน้องๆ มีหนังสือเล่มใหญ่มากๆ แล้วต้องการหาข้อมูลบางอย่าง ถ้าไม่มีสารบัญ น้องๆ จะต้องเปิดไปทีละหน้าๆ เสียเวลาสุดๆ Indexes ก็เหมือนสารบัญนั่นแหละ มันช่วยให้ database หาข้อมูลได้เร็วขึ้นมากๆ
CREATE INDEX idx_username ON users (username);
Code snippet ด้านบน สร้าง index บน column username ใน table users ลองเอาไปประยุกต์ใช้กันดูนะ
Execution Plan คือ แผนการทำงานของ database ที่มันจะบอกว่ามันจะ execute query ของเรายังไง มันจะใช้ index อะไร จะ join table ไหนก่อนหลัง การอ่าน execution plan จะช่วยให้เราเห็น bottleneck และรู้ว่าควรจะ optimize ตรงไหน
วิธีดู Execution Plan ก็ขึ้นอยู่กับ database ที่น้องๆ ใช้นะ ลองหาใน Google ดู เช่น "MySQL explain query" หรือ "PostgreSQL explain analyze"
เอาล่ะ! มาถึงขั้นตอนการใช้งานจริงกันบ้าง พี่จะบอกว่ามันไม่ได้ยากอย่างที่คิดนะ แค่ต้องรู้หลักการและฝึกฝนบ่อยๆ
ขั้นตอนแรกคือการวิเคราะห์ query ของเราอย่างละเอียด ดูว่ามันทำงานยังไง มันดึงข้อมูลอะไรบ้าง มี join กี่ table มี where clause แบบไหนบ้าง
SELECT * FROM orders WHERE customer_id = 123 AND order_date > '2023-01-01';
ลองดู query ด้านบน มันดึงข้อมูลจาก table orders โดยมีเงื่อนไข customer_id และ order_date เราต้องดูว่า column เหล่านี้มี index หรือยัง ถ้ายังไม่มี ก็ควรสร้าง
อย่างที่บอกไปแล้วว่า Execution Plan สำคัญมากๆ ใช้ EXPLAIN (หรือ EXPLAIN ANALYZE ในบาง database) เพื่อดูว่า database มัน execute query ของเรายังไง
EXPLAIN SELECT * FROM orders WHERE customer_id = 123 AND order_date > '2023-01-01';
ผลลัพธ์ที่ได้จะบอกว่า database มันใช้ index อะไร มัน scan กี่ row มีการ join table ไหนบ้าง ถ้าเห็นว่ามัน Full Table Scan (คือ scan ทั้ง table) แสดงว่าต้องปรับปรุงแล้วล่ะ
หลังจากที่ได้ Execution Plan มาแล้ว เราก็มาเริ่มปรับปรุง query และ structure ของ database กัน
WHERE clause ไม่มี index ให้สร้าง index ซะ= มากกว่า LIKE ถ้าเป็นไปได้SELECT *: เลือกเฉพาะ column ที่ต้องการใช้เท่านั้นสมัยพี่ทำร้านเน็ต เคยเจอเคสที่ query ช้ามากๆ เพราะ SELECT * ดึงข้อมูลที่ไม่จำเป็นมาเยอะแยะ พอเปลี่ยนเป็นเลือกเฉพาะ column ที่ต้องการ ปรากฏว่า query เร็วขึ้น 10 เท่า! (อันนี้ไม่ได้โม้)
การ optimize query ไม่ใช่ทางออกเดียวเสมอไป บางครั้งเราอาจจะต้องพิจารณาทางเลือกอื่นด้วย เช่น
ลองดูตารางเปรียบเทียบกัน
| ทางเลือก | ข้อดี | ข้อเสีย |
|---|---|---|
| Optimize Query | ไม่ต้องลงทุนเพิ่ม, ปรับปรุงประสิทธิภาพโดยตรง | ต้องใช้ความรู้และประสบการณ์, อาจต้องปรับ database structure |
| Caching | ลด load บน database, เพิ่มความเร็วในการตอบสนอง | ต้องจัดการ cache ให้ดี, ข้อมูลใน cache อาจไม่ update |
| Read Replica | ลด load บน database หลัก, เพิ่ม availability | ต้องมี infrastructure เพิ่ม, ข้อมูลอาจไม่ consistent |
| NoSQL Database | เหมาะกับข้อมูลที่ไม่มีความสัมพันธ์ซับซ้อน, scale ได้ง่าย | ต้องเรียนรู้เทคโนโลยีใหม่, อาจไม่เหมาะกับทุก use case |
หวังว่าน้องๆ จะได้ประโยชน์จากบทความนี้กันนะ อย่าลืมแวะไปอ่านบทความอื่นๆ ใน SiamCafe Blog ด้วยล่ะ มีอะไรดีๆ อีกเยอะเลย!
อ้อ! พี่ลืมบอกไปว่า การ optimize query มันเป็นกระบวนการที่ไม่จบสิ้น เราต้อง monitor query ของเราอยู่เสมอ และปรับปรุงมันเรื่อยๆ ตามการเปลี่ยนแปลงของข้อมูลและ traffic นะจ๊ะ
สุดท้ายนี้ พี่ขอฝากคำคมไว้ "Practice makes perfect" ฝึกฝนบ่อยๆ แล้วน้องๆ จะเก่งเองแน่นอน! อย่าลืม SiamCafe Blog นะ มีอะไรดีๆ รออยู่อีกเพียบ!
อ่ะน้อง ฟังพี่นะ สมัยผมทำร้านเน็ต SiamCafe เมื่อ 20 กว่าปีก่อน Database นี่สำคัญสุดๆ เพราะต้องเก็บ User, Log, Billing ทุกอย่าง ถ้าช้าเน็ตก็กระตุก ลูกค้าก็หายหมด
ผมเลยต้อง Optimize Query ตลอดเวลา ลองผิดลองถูกเยอะมาก จนได้เคล็ดลับที่อยากมาแชร์ให้ฟังกัน
Index เนี่ยเหมือนสารบัญหนังสือ ถ้าเราสร้าง Index ใน Column ที่ใช้ค้นหาบ่อยๆ Database จะหาข้อมูลได้เร็วขึ้นมาก
แต่! ไม่ใช่ว่าใส่ Index ไปทุก Column แล้วจะดีนะ มันก็เหมือนสารบัญเยอะเกินไป อ่านยากเปล่าๆ เลือกใส่เฉพาะที่จำเป็นจริงๆ
อันนี้เจอบ่อยมาก น้องๆ มักจะเขียน SELECT * FROM table ซึ่งมันดึงทุก Column ออกมา ทั้งๆ ที่เราอาจจะใช้แค่ 2-3 Column เอง
เปลี่ยนเป็น SELECT column1, column2 FROM table จะช่วยลดปริมาณข้อมูลที่ต้องส่งผ่าน Network และประมวลผลได้เยอะ
EXPLAIN PLAN คือเครื่องมือวิเคราะห์ Query ที่ Database มีให้ ใช้ดูว่า Database จะ Query ยังไง ใช้ Index อะไรบ้าง
EXPLAIN SELECT * FROM users WHERE username = 'testuser';
ถ้าเห็นว่ามัน Full Table Scan (คืออ่านทั้ง Table) แสดงว่าต้องปรับปรุงแล้ว อาจจะต้องเพิ่ม Index หรือเปลี่ยนวิธีเขียน Query
บางที Query มันซับซ้อนเกินไป ทำให้ Database งง ลองแบ่งเป็น Query ย่อยๆ แล้วค่อยเอาผลลัพธ์มารวมกัน อาจจะเร็วกว่าก็ได้
เหมือนเราทำงานชิ้นใหญ่ๆ ถ้าแบ่งเป็นงานย่อยๆ แล้วค่อยๆ ทำ มันจะง่ายกว่าใช่ไหมล่ะ Database ก็เหมือนกัน
หลายสาเหตุเลยน้อง เช่น ข้อมูลใน Table เยอะขึ้น Index ที่เคยใช้ อาจจะไม่เหมาะสมแล้ว หรือมีการเปลี่ยนแปลง Configuration ของ Database
มีแน่นอน! เพราะทุกครั้งที่เรา Insert, Update, Delete ข้อมูลใน Table ที่มี Index Database จะต้อง Update Index ด้วย ทำให้การเขียนข้อมูลช้าลง
Database ส่วนใหญ่จะมี Tools ให้ Monitor Query ที่ใช้เวลานานๆ เราสามารถใช้ Tools เหล่านั้น เพื่อหา Query ที่ต้อง Optimize เป็นพิเศษได้
การ Optimize Query เป็นเรื่องที่ต้องทำตลอดเวลา ไม่มีสูตรสำเร็จตายตัว ต้องเข้าใจ Database, เข้าใจข้อมูล และลองผิดลองถูก
สมัยผมทำร้านเน็ต SiamCafe ผมต้อง Optimize Query ทุกวัน เพราะลูกค้าทุกคนคือเงิน คือถ้าเน็ตช้า ลูกค้าก็ไปเล่นร้านอื่น iCafeForex ก็ต้อง optimize เหมือนกันนะ
หวังว่าเคล็ดลับที่พี่แชร์ให้ จะเป็นประโยชน์กับน้องๆ นะ ลองเอาไปปรับใช้กันดู แล้วอย่าลืมแวะมาอ่านบทความอื่นๆ ใน SiamCafe Blog ด้วยล่ะ!