Random Row เรื่องเล็กๆ ที่สามารถสร้างปัญหาใหญ่ๆ
หลังจากที่มีข้อมูลใน Database MySQL เยอะขึ้นแล้ว สิ่งที่มองข้ามในหลาย ๆ จุดก็เริ่มแสดงผลขึ้น
เรื่องง่ายอย่างเช่นการสุ่มแสดงผลโดยใช้ RAND() ใน Mysql กลับใช้ทรัพยากรอย่างมากในการสุ่มแต่ละครั้ง
ทำให้ Server เริ่มเกิดอาการโหลดหนัก เนื่องจากมีการสุ่มข้อมูลเพื่อนำไปใช้ตลอด
(กว่าจะเจอต้นตอของความช้าก็ไล่ Benchmark Code แต่ละส่วนนานอยู่)
สำหรับเว็บที่มีแถวข้อมูลเป็นจำนวนมาก การใช้ RAND() นั้นไม่เหมาะแน่ ข้างล่างคือ Code เจ้าปัญหา
[Codeigniter]
$query = $this->db->limit(1)->order_by(‘unique_id’, ‘random’)->get(‘product’);
ผลลัพธ์ที่ออกมาได้หลังจาก Benchmark คือ 0.0693 วินาที อาจดูไม่มาก
แต่ด้วยจำนวน Req กับการที่ MySQL มันซด CPU ไปเยอะ แทบจะโดน VPS Provider เตะออก
คราวนี้มาแก้ไขกัน
ทั่วไปเค้าจะให้นำตัวเลขที่เป็น ID [auto increasement] มาหาค่า MAX แล้วสร้าง Random ตัวเลขเปล่าขึ้นมา
หลังจากนั้นก็นำตัวเลขนั้นไป Query Where ตรง ๆ แต่ในกรณีของผม ตัวตาราง DB ของสคริปนั้นไม่ได้มี AI Number
จึงเปลี่ยนมาใช้การตั้ง Limit Offset แทน ตัวอย่างโค๊ด ด้านล่าง
$count = $this->db->count_all_results(‘product’);
$query = $this->db->limit(1, rand(1, $count))->get(‘product’);
ผลลัพธ์ที่ได้คือ 0.0079 วินาที ไวกว่าเกือบ 10 เท่า และไม่ต้องกังวลเมื่อมี Product เพิ่มมากขึ้น
หลังจากที่ได้นำวิธีนี้ไปลองใช้ สามารถลดการใช้ CPU ไปได้อีกเยอะ