ดึงข้อมูลออกมาแสดงแล้วช้ามากๆ ช่วยดูโค๊ช และแนวทางแก้ไขหน่อยคับ
ผมใช้ฐานข้อมูล mysql และจำเป็นต้องเชื่อมกัน 5 ตาราง ข้อมูลค่อนข้างเยอะ จึงจำเป็นต้องมี 5 ตาราง
ติดปัญหาตอนแสดงข้อมูลครับ ข้อมูลก็ยังมีไม่มากตอนนี้มีประมาณ 3000 เร็คคอร์ด (แต่อนาคตก็ต้องมีมากกว่า 50,000 เร็คคอร์ด) ตอนแสดงข้อมูลมันช้ามากๆ เน็ต 5M รอโหลดข้อมูลประมาณ 10 วิ ทั้งๆ ที่ทำการแบ่งหน้าแล้วนะครับ
ถ้า table เดียว ไม่ต้องรอโหลดเลยกดปุ๊บ แสดงเลย ผมเลยเข้าใจว่าเป็นที่การ join แน่ๆ ที่ทำให้มันแสดงช้า หรือว่าเป็นที่การแบ่งหน้า เพราะเคยลองเขียนให้มัน limit 20 มันก็แสดงเร็วดีไม่มีปัญหา แต่พอให้มันแบ่งหน้า หน้าละ 20 มันก็ช้าทันที
แนวทางแก้ไขต้องทำยังไงครับ เพื่อนๆ พี่ๆ ทำยังไงให้ดึงข้อมูลออกมาแสดงเร็วๆ ครับ
รบกวนด้วยครับ คิดไม่ออกจริงๆ (ลูกค้าเริ่มบ่นแล้วว่ามันช้า...... )
โค๊ชเป็นดังนี้ครับ............................................................
//ดึงฐานข้อมูลและ join
$sql = "SELECT user_personal.id_user,user_personal.position1,user_personal.pic_resu, user_personal.position2,user_personal.salary1,user_personal.sex, user_personal.birthday,user_personal.province,user_edu.levelstudy1, user_edu.cerstudy1,user_edu.namestudy1,user_edu.levelstudy2, user_edu.cerstudy2,user_edu.namestudy2,user_work.startwork, user_work.trainname1,user_skill.capable,user_skill.project, user_login.hide FROM user_personal";
$sql .= " LEFT JOIN user_edu ON (user_personal.id_user = user_edu.id_user)";
$sql .= " LEFT JOIN user_work ON (user_personal.id_user = user_work.id_user)";
$sql .= " LEFT JOIN user_skill ON (user_personal.id_user = user_skill.id_user)";
$sql .= " LEFT JOIN user_login ON (user_personal.id_user = user_login.id)";
$sql .= " where hide = '1' ".$textjt .$textsalary .$textstudy .$textkeyword .$textsorth;
//นำข้อมูลที่ได้มาแบ่งหน้า
$result=mysql_query($sql);
$nrow=mysql_num_rows($result);
$totalpage=ceil($nrow/$pagelen_trav);
$goto_trav=($page-1) * $pagelen_trav;
$start_trav=$page-$range;
$end_trav=$page+$range;
if($start_trav<=1){$start_trav=1;}
if($end_trav>=$totalpage){ $end_trav=$totalpage;}
$sql="$sql LIMIT ".$goto_trav.",".$pagelen_trav."";
$result=mysql_query($sql);
$nrow=mysql_num_rows($result);Tag : PHP, MySQL
Date :
2010-08-13 18:16:17
By :
i5z
View :
4018
Reply :
12
ช่วยตอบหน่อยนะครับ ได้โปรดดดด
Date :
2010-08-15 21:29:10
By :
i5z
optimize ได้ ก็ ทำ
cache ถ้าข้อมูลไม่อัพเดทบ่อย
ลดตารางถ้าทำได้
ไม่ทราบว่าหน้านี้ใช้บ่อยแค่ไหนคับ
Date :
2010-08-15 22:34:58
By :
pjgunner
memcache ลอง search google ดูค่ะ
Date :
2010-08-15 22:45:11
By :
atomy_mink
แคชคือหลักการเก็บข้อมูลไว้ในไฟล์ หรือ db ก็ได้ มันทำให้เราลดการคิวรี่ (ช้าๆแบบนี้) ให้น้อยครั้งลง หรือตั้งเวลา ไว้ มีหลายวิธีแล้วแต่สะดวก
แต่มันก็มีข้อได้เปรียบในบางกรณีเท่านั้น ถ้าหากระบุุใน where แบบนี้อาจมีการแคชเยอะมาก(แต่ละ id) แต่มันก็ช่วยให้ดึงข้อมูลได้เร็วขึ้นมากกว่าถ้าหากว่า ข้อมูลด้านในไม่อัพเดทบ่อย อาจพิจารณาแคช เป็นราย id ครับ
แต่ลักษณะนี้ผมอาจแนะนำให้ลอง ทำการรวมข้อมูลขึ้นมาครับ ในตารางเดียว (สำหรับการนี้โดยเฉพาะ)
โดย สร้างตารางที่มีฟีลทั้งหมดขึ้นมาอีกอัน operation ไหนมีผลกับข้อมูลเหล่านี้ ก็ให้มาอัพเดทครับ แยกเป็นราย id ไป
แต่อาจทำให้ระบบทำงานซ้ำซ้อน ในส่วนอื่น เพราะต้องทำการคิวรี่สองครั้ง 1. ปรกติ 2. ตารางใหม่นี้
แต่ถ้าระบบอื่นไม่มีปัญหาช้าแล้ว มันจะช่วยทำให้ระบบนี้ทำงานได้ไวมากขึ้นครับ เพราะการจอยแล้วมันจะสร้าง ตารางในหน่วยความจำเป็นครั้งๆไปครับ ดังนั้นผมว่าทำอีกตารางก็เป็นทางที่ไม่เลว สำหรับระบบที่มีอยู่แล้ว และช่วยรองรับการเพิ่มปริมาณเรคคอร์ดได้ดีกว่าคับ
Date :
2010-08-15 22:53:54
By :
pjgunner
memcache อยู่้ที่ server support หรือเปล่านะครับ
Date :
2010-08-15 22:56:15
By :
PlaKriM
สร้าง index ในฟิลด์ที่จอยกันช่วยได้
Date :
2010-08-15 22:57:36
By :
PlaKriM
อืม... อาจต้อง ลดตารางที่ดึงมา join หรือสร้างตารางเพิ่มอย่างที่คุณ เอี่ยว ว่า
ขอบคุณครับที่ช่วยตอบ
Date :
2010-08-16 11:54:24
By :
i5z
อย่างดึงข้อมูลทั้งก้อนครับ database ของผม 200,000 กว่า ยังสบายเลย ให้สร้าง table ประเภท tempfile ก่อน แสดงจริงครับ ไม่เช่นก็อืดๆๆๆๆๆๆๆๆๆๆๆๆๆๆๆๆครับ
Date :
2010-08-17 07:15:40
By :
p_kokmas
$sqlCount = "SELECT COUNT(*) AS c FROM user_personal";
$sqlCount .= " LEFT JOIN user_edu ON (user_personal.id_user = user_edu.id_user)";
$sqlCount .= " LEFT JOIN user_work ON (user_personal.id_user = user_work.id_user)";
$sqlCount .= " LEFT JOIN user_skill ON (user_personal.id_user = user_skill.id_user)";
$sqlCount .= " LEFT JOIN user_login ON (user_personal.id_user = user_login.id)";
$sqlCount .= " where hide = '1' ".$textjt .$textsalary .$textstudy .$textkeyword .$textsorth;
$result=mysql_query($sqlCount);
$nrow=mysql_result($result,0);
โดยปกติแล้วควรจะใช้คำสั่ง query count นี้แทนการ mysql_num_rows จาก query ตรงๆ ครับ
เพราะ mysql_query จะมีการดึงข้อมูลมาเก็บไว้ใน buffer ซึ่งใช้หน่วยความจำมากครับ
อีกอย่างให้สร้าง index key ให้กับ field ที่ join ด้วยครับ
Date :
2010-08-17 09:31:30
By :
num
ปกติข้อมูลที่ดึงมาใช้บ่อย ๆ ไม่ควรมีขนาดใหญ่ครับ และถ้าไม่เป็น ผมจะไม่ใช่การ JOIN
Date :
2010-08-17 09:33:51
By :
webmaster
Load balance : Server 05