ขอสอบถามวิธีการ Query หน่อยครับ มันค่อนข้างกิน CPU มากเลย ดู Query ข้างในครับ
ผมเขียน query ตามนี้เลยครับ เท่าที่คิดได้ มันต้อง วน ซ้อน กันแบบนี้อะครับ ตัว query ที่สาม จะข้อมูลเยอะสุด ประมาณ 1-2 ล้าน record ได้
query ที่ 1 จะวนเอา FacName มาเขียนไว้เป็นหัวข้อหลัก --> 7 record
query ที่ 2 จะวนเอา DepName ที่อยู่ใน FacName นั้นๆ มาเป็นหัวข้อรอง --> ประมาณ 60 record
Query ที่ 3 จะประมาณว่า เอา SubID ที่ เกิดจากการลงทะเบียนของนักเรียน ที่อยู่ใน DepName และ FacName นั้นๆ มาแสดง --> ข้อมูลจะเยอะสุด ประมาณ 1-2 ล้าน record
พอนำมารันแล้ว CPU วิ่งไป 98% เลยครับ ค่อนข้างกิน CPU มากเลยครับ
ใครมีวิธี query ดีๆ แนะนำ หรือจะสามารถทำให้ query ได้เร็วขึ้น ใช้ ทรัพยากร CPU น้อยลงมั่งครับ แนะนำทีครับ ขอบคุณครับ
Code (PHP)
<?php
$term = isset($_GET['term']) ? $_GET['term'] : '';
$years = isset($_GET['years']) ? $_GET['years'] : '';
$groups_id = isset($_GET['groups_id']) ? $_GET['groups_id'] : '';
$groups_name = '';
if($groups_id == '1'){
$groups_name = 'ภาคปกติ';
}else{
$groups_name = 'ภาค กศ.บป.';
}
include 'var/db_conn.inc.php';
$sql_fac = "
SELECT
FacID, FacName
FROM
FacSchool
ORDER BY
FacID ASC;
";
$param = array();
$query = $conn->prepare($sql_fac);
$query->execute($param);
while($rs = $query->fetch(PDO::FETCH_ASSOC)){
?>
<b>
<?=$rs["FacName"];?>
</b>
<?php
$sql_DepSchool = "
SELECT
d.DepID, d.DepName
FROM
DepSchool d
WHERE
d.FacID = :fac_id
ORDER BY
d.DepName ASC
";
$param2 = array(":fac_id"=>$rs["FacID"]);
$query2 = $conn->prepare($sql_DepSchool);
$query2->execute($param2)
while($rs2 = $query2->fetch(PDO::FETCH_ASSOC)){
?>
<table border="1" width="100%" cellspacing="1" cellpadding="0">
<tr>
<td colspan="8" align="center"><?php echo $rs2["DepName"];?></td>
</tr>
<tr>
<td align="center">ที่</td>
<td align="center">รหัสวิชา</td>
<td align="center">ชื่อวิชา</td>
<td align="center">หน่วยกิต</td>
<td align="center">จำนวนนักศึกษา</td>
</tr>
<?php
$sql_ftes = "
SELECT
d.DepName, s.SubID, s.SubName, s.Credit,
COUNT(r.ID) AS Total
FROM
RegSchool r
INNER JOIN RegDetailSchool rd ON r.RID = rd.RID
INNER JOIN SubSchool s ON s.RefID = rd.RefID
INNER JOIN DepSchool d ON d.DepID = s.DepID
INNER JOIN FacSchool f ON f.FacID = d.FacID
WHERE
d.DepID = :dep_id
AND r.Term = :term
AND r.Years = :years
AND rd.GID = :g_id
GROUP BY
s.SubName, s.Credit, d.DepName, s.SubID
ORDER BY
s.SubName ASC
";
$param3 = array(":dep_id"=>$rs2["DepID"], ":term"=>$term, ":years"=>$years, ":g_id"=>$groups_id);
$query3 = $conn->prepare($sql_ftes);
$query3->execute($param3)
$sch = 0;
$sum_sch = 0;
$ftes = 0;
$sum_ftes = 0;
$rate = 0;
$sum_rate = 0;
$count = 0;
while($rs3 = $query3->fetch(PDO::FETCH_ASSOC)){
$count++;
$sch = cal_sch($rs3["Credit"], $rs3["Total"]);
$ftes = cal_ftes($sch);
$rate = cal_rate($ftes);
$sum_sch += $sch;
$sum_ftes += $ftes;
$sum_rate += $rate;
?>
<tr>
<td><?php echo $count;?></td>
<td><?php echo $rs3["SubID"];?></td>
<td><?php echo $rs3["SubName"];?></td>
<td><?php echo $rs3["Credit"];?></td>
<td><?php echo $rs3["Total"];?></td>
</tr>
<?php
}
?>
</table>
<br/>
<?php
}
?>
<br/>
<?php
}
?>
Tag : PHP, Ms SQL Server 2012
Date :
2016-02-15 22:47:36
By :
angelkiller9
View :
1614
Reply :
6
067.INNER JOIN DepSchool d ON d.DepID = s.DepID
068.INNER JOIN FacSchool f ON f.FacID = d.FacID
2 บันทัดนี้ ควรได้ result มาจากการคิวรี่ ด้านบนแล้ว
069.WHERE
070.d.DepID = :dep_id
แก้เป็น
Code (SQL)
WHERE
s.DepID = :dep_id
สำหรับ
GROUP BY s.SubName, d,DepName s.Credit, s.SubID
DepName เป็นส่วนหนึ่งของ Depschool
ทั้งหมดของการคิวรี่นี้ มีข้อมูลจำเพาะจาก WHERE s.DepID = :dep_id อยู่แล้ว ไม่ต้องนำมา group อีก
Date :
2016-02-16 08:13:51
By :
Chaidhanan
อาจจะลดได้อีกนิด ถ้า s.SubID มี s.SubName เดียว อ้างอิง record เดียวกัน
ก็ตัด group by SubName ออก เหลือแค่ Credit กับ SubID
การเอา varchar มา group มันเปลือง cpu มากกว่า เอา interger มา group นะครับ
group ยิ่งสั้นยิ่งเร็ว ใช้ cpu ในการเปรียบเทียบน้อยลง
แต่การใช้งาน cpu 100% ระยะเวลาสั้นๆ ไม่เป็นปัญหาครับ
แต่ถ้ามันนานมันทำงานหนัก ปัญหาคือเรื่องความร้อน เครื่องอาจจะเสื่อมเร็วขึ้น
Date :
2016-02-16 10:10:50
By :
Chaidhanan
ไม่แน่ใจว่าจะเร็วกว่า ลองดูครับ ไม่ได้ทดสอบกับ sqlserver นานแล้ว
Code (SQL)
select n.SubID, n.Credit, n.SubName, tmp.Total
From (
SELECT s.SubID, s.Credit, count(r.ID) AS Total
from RegSchool AS r, RegDetailSchool AS rd, SubSchool AS s
WHERE s.DepID = :dep_id AND s.RefID = rd.RefID
AND r.RID = rd.RID AND r.Term = :term AND r.Years = :years
AND rd.GID = :g_id
GROUP BY s.Credit, s.SubID
) AS tmp
left join SubSchool AS n
ON n.SubID=tmp.SubID and n.Credit=tmp.Credit
ORDER BY n.SubName
Date :
2016-02-16 12:19:52
By :
Chaidhanan
Load balance : Server 05