การ select ข้อมูลจาก table ใหญ่ ๆ ในฐานข้อมูล MySQL

1 ส.ค. 2018 , 4,947 Views   , หมวดหมู่ MySQL โค๊ดดิ้ง   , ป้ายกำกับ:,


ผลลัพธ์อันเลวร้ายที่เกิดกับการ select ข้อมูลจาก table ใหญ่ ๆ ในฐานข้อมูลมีอยู่สถานเดียวนั่นก็คือ .. ช้าโคตร ๆ ๆ ๆ ๆ ยิ่งถ้ามีคนร่วมด้วยช่วยกัน select แล้วล่ะก็ ต้องบอกว่า .. ช้าโคตร ๆ ๆ ๆ ๆ ยกกำลังด้วยจำนวนคนที่ค้น!!!

ดังนั้นหากเราไม่อยากจะเจอกับเรื่องเลวร้ายเช่นนี้ งั้นเรามาทราบกฎกันดีกว่า ว่าเราควรจะทำยังไงกันดี?

กฎข้อแรก อย่าออกแบบตามหลักการ Normalization

  • เพราะการแยกข้อมูลกระจายไว้ตาม table ต่าง ๆ ตามหลักการ Normalization นั้น มันดูดี๊ดูดีในทางทฤษฎี แต่มันใช้ไม่ได้เลยในทางปฏิบัติ โดยเฉพาะหากต้อง join table เยอะ ๆ ซึ่งมีข้อมูลมาก ๆ หรือใช้ subquery แล้วล่ะก็ … ไอ้ Normalization เนี่ยแหล่ะ มันจะรัดคอตัวมันเอง

กฎข้อสอง อย่าเลือกข้อมูลเกินความจำเป็น

  • ยกตัวอย่างเช่น select * from person โดย table ชื่อ person มีฟิลด์เป็นร้อย แต่ดันใช้แค่ฟิลด์ id กับ name … งั้นก็เปลี่ยนเป็น select id, name from person ดีกว่ามั๊ง!!

กฎข้อสาม ระบุ index ให้ชัดเจนไปเลย

  • ตามหลักแล้ว table ทุกอันควรมี primary key และ index เพื่อความรวดเร็วในการค้นหา ซึ่งบาง table อาจจะมี index มากกว่าหนึ่งตัว งั้นแทนที่เราจะเขียนว่า select id, name from person where name = “ยิปซี” เราก็ระบุเป้ง ๆ ไปเลยว่าเราจะใช้ index ตัวไหน เช่น select id, name from person where name = “ยิปซี” use index (ix_name) เป็นต้น

กฎข้อสี่ อย่ายึด table ไว้คนเดียว

  • ไอ้เจ้า table ก็เปรียบได้กับสมบัติ มันต้องผลัดกันชม ดังนั้นการยึดเอาไว้ select แค่คนเดียวมันก็เกินไป เพราะมีคนอื่นเข้าแถวรอ select อยู่ จะเป็นการทำให้ชาวบ้านเขาเสียเวลาได้ งั้นที่ถูกต้องก็คือ พอ select ได้แล้วก็รีบ ๆ ลอกเอาไปไว้อีกที่นึง จากนั้นก็เชิญไปคุ้ยแคะข้อมูลที่เลือกไปได้ตามสบาย โดยการ select sql_buffer_result id, name from person where name = “ยิปซี” แบบนี้

กฎข้อห้า ต้องรู้จักการ Recycle

  • ข้อมูลบางชุดมีคนต้องการเยอะ ไอ้ครั้นจะให้ฐานข้อมูลค้นซ้ำ ๆ มันก็เปลืองแรงไป งั้นค้นทีเดียวเก็บเอาไว้ แล้วแจกจ่ายให้คนที่ต้องการภายหลังดีกว่า โดยการ select sql_cache id, name from person where name = “ยิปซี” เป็นต้น

กฎข้อหก เอากฎข้อหนึ่งถึงกฎข้อห้ามารวมกัน

  • ก็จะได้แบบนี้ select sql_buffer_result sql_cache id, name from person where name = “ยิปซี” use index(ix_name)

แต่กฎย่อมไม่มีความตายตัว ดังนั้นกฎใหม่ย่อมจะสามารถแทนที่กฎเก่าได้เสมอ ดังนั้นถ้าใครทำให้มันเร็วกว่านี้ได้ ก็ไม่ต้องเชื่อกฎนี้ก็แล้วกันนะจ๊ะ

ที่มาครับ : http://www.parinya.net/node/1094


ป้ายกำกับ:,