การเขียนโปรแกรมด้วยภาษา php เป็นภาษาที่ยืดหยุ่น และผมถนัดที่สุด เพราะเราสามารถออกแบบการทำงานได้ง่ายกว่าภาษาอื่น ที่ผมเขียนเป็น เรื่องตัวแปรก็ยืดหยุ่น เรียกใช้ง่าย
บทความนี้จะนำเสนอเทคนิคการเขียนโปรแกรม ที่ช่วยลดจำนวนครั้งในการคิวรี่ฐานข้อมูลน้อยลง เพื่อเป็นการลดภาระของฐานข้อมูล MySQL ให้ใช้ CPU น้อยลง
แต่ก็ต้องแรก กับหน่วยความจำของโปรแกรมสักหน่อย เช่นถ้าใช้กับตารางที่เก็บข้อมูลหลักหมื่นเรคอร์ด ก็อาจจะเกิดอาการตัวแปรมีขนาดใหญ่เกินไป ซึ่งจะต้องใช้ memory_limit เพิ่มขึ้นไปอีก
กรณีที่ต้องแสดงข้อมูลหลายเรคอร์ดเรามักจะเจอ fatal error “Allowed memory size exhausted” ข้อความนี้อยู่เป็นประจำ จึงเป็นเหตุผลให้เราต้องแบ่งหน้าการแสดงผล เพื่อให้แสดงผลเร็วขึ้น และไม่ใช้หน่วยความจำเกินขีดจำกัด
ขั้นการเขียนโปรแกรมที่จะช่วยลดจำนวนการคิวรี่ MySQL คือ
1. ตัดส่วนที่ต้องคิวรี่เพื่อดึงข้อมูลในลูปออกมาไว้นอกลูป
วิธีนี้จะสามารถใช้ได้กับ ตารางข้อมูลที่ข้อมูลตายตัว หรือมีการเพิ่มข้อมูลไม่บ่อย และจะไม่เกินหลักพัน ประมาณนี้
2. สร้างอาร์เรย์เก็บข้อมูลของตารางที่ต้องคิวรี่ในลูปนี้ เอาไว้เรียกใช้ในลูปแทนการคิวรี่จากฐานข้อมูล
เพียงแค่นี้ก็ช่วยให้โปรแกรมทำงานได้เร็วขึ้นแล้วครับ สำหรับตารางไหนที่สามารถใช้วิธีนี้ได้บ้างนั้นต้องอยู่ในดุลพินิจของใครของมันนะครับ ส่วนที่ผมใช้งานบ่อยๆ ก็เช่น ฐานข้อมูล ตารางรายชื่อพนักงาน ตารางรายชื่อแผนก ตารางรายชื่อฝ่าย ตารางรายชื่อวัสดุ ซึ่งรวมๆ แล้วคือตารางที่เป็นตารางหลักครับ
การเขียนโค๊ด PHP แบบเดิม (เรียกข้อมูลในลูป)
<?php $no = 0; $sql = "SELECT * FROM booking WHERE month = '04' "; $result = mysql_query($sql);//คิวรี่ครั้งที่ 1 while( $rs = mysql_fetch_assoc($result) ){ $dpId = $rs["book_department_id"]; //คิวรี่ครั้งที่ 2 $qry = mysql_query("SELECT department_name FROM tb_department WHERE department_id = '".$dpId."' "); $rsDp = mysql_fetch_assoc($qry); $departMentName = $rsDp["department_name"]; echo "<br/>", $departMentName; } ?>
คิวรี่ครั้งที่ 1 :: คือการเรียกข้อมูลการจองของเดือนเมษายน
คิวรี่ครั้งที่ 2 :: คือการการเรียกชื่อแผนกที่พนักงานคนที่รับจองสังกัดอยู่ ซึ่งถ้าเดือนเมษายนมีการจอง 50 รายการ ก็จะเรียกคำสั่งคิวรี่ทั้งหมด 50 ครั้งเช่นกัน
การเขียนโค๊ด PHP แบบใหม่ (แยกส่วนที่เรียกข้อมูลในลูป ออกมาไว้นอกลูป)
<?php //รายชื่อแผนกทั้งหมด $allDepart = array(); $qry = mysql_query("SELECT department_id, department_name FROM tb_department"); while($rsDp = mysql_fetch_assoc($qry)){ $allDepart[$rsDp['department_id ']] = $rsDp['department_name'] } $no = 0; $sql = "SELECT * FROM booking WHERE month = '04' "; $result = mysql_query($sql); while( $rs = mysql_fetch_assoc($result) ){ $dpId = $rs["book_department_id"]; $departMentName = $allDepart[$dpId]; echo " ", $departMentName; } ?>
คิวรี่ครั้งที่ 2 :: คือการเรียกข้อมูลการจองของเดือนเมษายน ถึงแม้เดือนนี้จะมี 50 รายการ แต่การคิวรี่จะเกิดขึ้นเพียง 2 ครั้งเท่านั้นเพราะรายชื่อแผนกทั้งหมดเก็บไว้ในอาร์เรย์ $allDepart แล้ว ซึ่งเรียกใช้ด้วยไอดีทันที
จากตัวอย่างการเขียนโค๊ดสองกรณีนี้ คงพอจะเห็นถึงความแตกต่างแล้วนะครับ กรณีเรียกข้อมูลทั้งหมดมาเก็บในตัวแปล $allDepart ถามว่าจะทำงานช้าไปรึเปล่า บอกได้เลยว่าไม่ช้าครับ
ผมเคยทดสอบกับข้อมูลตารางที่มีฟิลด์มากกว่า 50 ฟิลด์ เก็บข้อมูลมากกว่า 50,000 เรคอร์ด
และเรียกโดยการ SELECT * FROM table มาเก็บในตัวแปรอาร์เรย์ใช้เวลาเพียงไม่กี่วิครับ
แต่ทดสอบกับเซิร์ฟเวอร์ภายในนะครับ ไม่ได้ทดสอบผ่านอินเตอร์เน็ต แต่ถึงอย่างไรก็เร็วกว่ากรณีแรกอยู่ดีครับ
ปัญหาที่พบคือการใช้กับตารางที่มีข้อมูลเยอะเกินไป จะทำให้เกิดการใช้หน่วยความจำเกินที่กำหนดไว้ครับ ซึ่งผมก็ไม่แนะนำให้ทำ ก็ลองเอาไปปรับใช้กันดูนะครับ แล้วท่านจะเห็นว่าความเร็วต่างกันอย่างไร
ความคิดเห็น
แสดงความคิดเห็น