ข้ามไปที่เนื้อหาหลัก

จัดระเบียบซอร์สโค๊ด PHP ลดการ query ฐานข้อมูล MySQL ให้น้อยลง




การเขียนโปรแกรมด้วยภาษา 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;
}
?>


คิวรี่ครั้งที่ 1 :: คือการเรียกข้อมูลรายชื่อแผนกทั้งหมด
คิวรี่ครั้งที่ 2 :: คือการเรียกข้อมูลการจองของเดือนเมษายน ถึงแม้เดือนนี้จะมี 50 รายการ แต่การคิวรี่จะเกิดขึ้นเพียง 2 ครั้งเท่านั้นเพราะรายชื่อแผนกทั้งหมดเก็บไว้ในอาร์เรย์ $allDepart แล้ว ซึ่งเรียกใช้ด้วยไอดีทันที



จากตัวอย่างการเขียนโค๊ดสองกรณีนี้ คงพอจะเห็นถึงความแตกต่างแล้วนะครับ กรณีเรียกข้อมูลทั้งหมดมาเก็บในตัวแปล $allDepart ถามว่าจะทำงานช้าไปรึเปล่า บอกได้เลยว่าไม่ช้าครับ

ผมเคยทดสอบกับข้อมูลตารางที่มีฟิลด์มากกว่า 50 ฟิลด์ เก็บข้อมูลมากกว่า 50,000 เรคอร์ด
และเรียกโดยการ SELECT * FROM table มาเก็บในตัวแปรอาร์เรย์ใช้เวลาเพียงไม่กี่วิครับ
แต่ทดสอบกับเซิร์ฟเวอร์ภายในนะครับ ไม่ได้ทดสอบผ่านอินเตอร์เน็ต แต่ถึงอย่างไรก็เร็วกว่ากรณีแรกอยู่ดีครับ


ปัญหาที่พบคือการใช้กับตารางที่มีข้อมูลเยอะเกินไป จะทำให้เกิดการใช้หน่วยความจำเกินที่กำหนดไว้ครับ ซึ่งผมก็ไม่แนะนำให้ทำ ก็ลองเอาไปปรับใช้กันดูนะครับ แล้วท่านจะเห็นว่าความเร็วต่างกันอย่างไร


PHP CI MANIA PHP Code Generator 
โปรแกรมช่วยสร้างโค้ด ลดเวลาการเขียนโปรแกรม

สนใจสั่งซื้อเพียง 4,500 บาท
http://fastcoding.phpcodemania.com/



สนับสนุนค่ากาแฟผู้เขียนได้ที่

PayPal

ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

แจกฟรี!! ระบบต่างๆที่พัฒนาด้วย PHP สำหรับนำไปใช้ในงานต่างๆ

       สำหรับหลายท่านที่ขอโค้ดเข้ามาทาง Inbox ของเฟซบุ๊กแฟนเพจ หรือถามถึงระบบต่างๆหลังไมค์มานั้น ส่วนใหญ่ก็มีแจกอยู่แล้วในเว็บบอร์ด ThaiCreate.Com นะครับ และด้านล่างนี้ก็เป็นระบบต่างๆที่แจกให้นำไปลองใช้ลองศึกษากันครับ

สอนเขียน PHP แสดงการจองห้องประชุมแบบไฮไลท์ตามช่วงเวลา (แบบเชื่อมต่อฐานข้อมูล MySQL)

ตัวอย่าง ผลลัพธ์ที่ได้จากการจองในฐานข้อมูล ตาราง tb_room สร้างตารางรายชื่อห้องประชุม สำหรับ id นั้นเป็น Primarykey จะกำหนดให้สร้างอัตโนมัติ ทุกครั้งที่เราเพิ่มชื่อห้องประชุมใหม่ -- -- Database: `tobedev_example` -- -- -------------------------------------------------------- -- -- Table structure for table `tb_room` -- CREATE TABLE IF NOT EXISTS `tb_room` (   `id` int(11) NOT NULL,   `name` varchar(30) NOT NULL ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; -- -- Dumping data for table `tb_room` -- INSERT INTO `tb_room` (`id`, `name`) VALUES (1, 'ห้องประชุม 1'), (2, 'ห้องประชุม 2'), (3, 'ห้องประชุม 3'), (4, 'ห้องประชุม 4'), (5, 'ห้องประชุม 5'); -- -- Indexes for dumped tables -- -- -- Indexes for table `tb_room` -- ALTER TABLE `tb_room`   ADD PRIMARY KEY (`id`); -- -- AUTO_INCREMENT for dumped tables -- -- -- AUTO_INCREMENT for table `tb_room` -- ALTER TABLE `tb_room`   MODIFY `i...

การนำไอคอน มาแสดงบน Fullcalendar

เนื่องจากมีน้องคนหนึ่งให้ช่วยดูโค้ดเกี่ยวกับ Fullcalendar ให้หน่อย แล้วพอดีช่วงนี้ผมก็กำลังสนใจปฏิทิน Fullcalendar อยู่พอดี จึงลองหาสาเหตุที่ไม่สามารถแสดงข้อมูลจาก MySQL และไม่สามารถแทรก icon เข้าไปใน Fullcalendar ได้ จากที่สังเกตุได้ครั้งแรกคือ Error ที่ Console ของ Firefox เกี่ยวกับฟังก์ชั่นที่เขียนผิด และก็มีการ echo ค้างไว้ในส่วนของไฟล์ getCalendar.php ก็เลยจัดการทดสอบแล้วลบ echo ออกให้เหลือแค่ echo json_encode($event_array); ที่ได้ใช้งานจริงเท่านั้น ขั้นตอนการตรวจสอบความถูกต้องของโค้ด PHP 1) ต้องแน่ใจว่าคำสั่งที่เขียนไว้ สามารถดึงข้อมูลมาแสดงผลได้ด้วยการ echo $sql; 2) นำคำสั่งที่ได้ไปรันในโปรแกรมจัดการฐานข้อมูล ในที่นี้คือ phpMyAdmin 3) เมื่อตรวจสอบดูผลลัพธ์ที่ได้ หากถูกต้องมีข้อมูลก็แสดงว่าการ Query ทำงานได้ 4) มาดูการทำงานของ JavaScript ในส่วนของ jQuery มีการแจ้งเตือนที่ฟังก์ชั่น .on() ซึ่งจะใช้กับ jQuery เวอร์ชั่นใหม่เท่านั้น นั่นหมายถึงเวอร์ชั่น jQuery ที่มากับ Fullcalendar เป็นเวอร์ชั่นเก่า ก็ให้เปลี่ยนไปใช้ .live() แทน ก็จะทำงานได้ปกติ 5) ม...