我已经拉回了很多信息,因此,我的页面在大约22~24秒内加载。我能做些什么来优化我的代码吗?
下面是我的代码:<?php
$result_rules = $db->query("SELECT source_id, destination_id FROM dbo.rules");
while($row_rules = sqlsrv_fetch_array($result_rules)){
$result_destination = $db->query("SELECT pk_id, project FROM dbo.destination WHERE pk_id=" . $row_rules['destination_id'] . " ORDER by project ASC");
while($row_destination = sqlsrv_fetch_array($result_destination)){
echo "Destination project: ";
echo "<span class='item'>".$row_destination['project']."</span>";
echo "ID: ".$row_rules['destination_id']."<br>";
if ($row_rules['source_id'] == null) {
echo "Source ID for Destination ID".$row_rules['destination_id']." is NULL<br>";
} else {
$result_source = $db->query("SELECT pk_id, project FROM dbo.source WHERE pk_id=" . $row_rules['source_id'] . " ORDER by project ASC");
while($row_source = sqlsrv_fetch_array($result_source)){
echo "Source project: ";
echo $row_source['project'];
echo " ID: ".$row_rules['source_id']."<br>";
}
}
}
}
?>
我的表是这样的:
源表:pk_id:int,项目:varchar(50),特性:varchar(50),里程碑:varchar(50), reviewGroup:varchar(125), groupId:int
规则表:pk_id:int, source_id:int, destination_id:int, login:varchar(50), status:varchar(50), batchId:int, srcPGroupId:int, dstPGroupId:int
目的表:pk_id:int,项目:varchar(50),特征:varchar(50),里程碑:varchar(50), QAAssignedTo:varchar(50), ValidationAssignedTo:varchar(50),优先级:varchar(50), groupId:int
如果您需要优化查询的帮助,请提供模式的详细信息和解释计划的输出。
运行嵌套循环对性能不利。像这样在嵌套循环中运行查询会导致非常差的性能。在select中使用"*"也不利于性能(特别是当您只使用几个列时)。
你应该从优化你的PHP和合并查询开始:
$result_rules = $db->query(
"SELECT rule.destination_id, [whatever fields you need from dbo.rules]
dest.project AS dest_project,
src.project AS src_project,
src.pk_id as src_id
FROM dbo.rules rule
INNER JOIN dbo.destination dest
ON dest.pk_id=rule.destination_id
LEFT JOIN dbo.source src
ON src.pk_id=rule.source_id
ORDER BY rule.destination_id, dest.project, src.project");
$last_dest=false;
$last_src=false;
while($rows = sqlsrv_fetch_array($result)){
if ($row['destination_id']!==$last_dest) {
echo "Destination project: ";
echo "<span class='item'>".$row['dest_project']."</span>";
echo "ID: ".$row['destination_id']."<br>";
$last_dest=$row['destination_id'];
}
if (null===$row['src_id']) {
... I'll let you sort out the rest.
在(pk_id, project)
上添加索引,使其包含查询中重要的所有字段
-
确保pk_Id被索引:http://www.w3schools.com/sql/sql_create_index.asp
-
与其使用select *,不如只返回你需要的列,除非你需要所有的列。
-
我还建议将SQL代码移动到服务器并调用存储过程。
-
你可以考虑使用LIMIT如果你的后端是mysql: http://php.about.com/od/mysqlcommands/g/Limit_sql.htm .
我假设else子句是减慢代码速度的原因。我建议在开始时保存所有需要的数据,然后在else子句中再次访问数组。基本上,你不需要每次都运行这个。
$result_destination = $db->query("SELECT * FROM dbo.destination WHERE pk_id=" . $row_rules['destination_id'] . " ORDER by project ASC")
您可以更早地获取数据并使用PHP对其进行迭代。
$result_destinations = $db->query("SELECT * FROM dbo.destination ORDER by project ASC")
然后在后面的代码中使用PHP确定正确的目的地。这取决于你在做什么,它应该节省一些时间。
另一个需要考虑的问题是浏览器呈现php代码生成的html所花费的时间。你展示的数据越多,花的时间就越长。根据受众的需求,您可能希望一次只显示x条记录。
有一些jquery方法可以增加显示的记录数量,而不需要返回到服务器。
对于初学者来说,您可能希望减少查询的运行次数。例如,执行一个查询,循环遍历这些结果并运行另一个查询,然后循环遍历该结果集运行更多查询通常被认为是不好的。运行的查询数量呈指数级增长。
例如,如果第一个查询返回100行,每个子查询返回10行。第一个查询返回循环遍历的100行。对于你再次查询的每一个。您现在有101个查询。然后,对这100行中的每一行运行另一个查询,每个查询返回10行。您现在有1001个查询。每个查询都必须向服务器发送数据(查询文本),等待响应并获取数据。这就是为什么要花这么长时间。
使用连接对所有表执行单个查询并遍历单个结果。