我的网站www.guidedsolutions.co.uk是很久以前构建的,我对php并不了解很多,但是当我进入搜索crieteria即苏格兰的医疗销售工作时,搜索结果加载速度非常快,但是当我点击时在搜索所有结果页面加载非常非常慢,有时甚至不加载。这是它的直接链接:www.guidedsolutions.co.uk/medical_devices/search_results.php 我不确定要复制哪个部分的php,这就是我发送链接的原因,但是如果我能提供更多信息请告诉我。 非常感激。
**
$conds_cat = "";
$conds_loc = "";
$conds_sec = "";
$conds_sal = "";
if (isset($i["start"]) && $i["start"] > 0)
$start = $i["start"];
if (isset($i["limit"]) && $i["limit"] > 0)
$limit = $i["limit"];
if(isset($i["category"]) && $i["category"] != "")
$conds_cat = "AND ".CAT_TABLE."_id ='".$i["category"]."'";
if(isset($i["location"]) && $i["location"] != "")
$conds_loc = "AND ".LOC_TABLE."_id ='".$i["location"]."'";
$searchstring = "&category=".$i["category"]."&location=".$i["location"]."&limit=".$i["limit"];
$sql = "SELECT * FROM ".JOB_TABLE." LEFT JOIN (".JBC_TABLE.", ".JBL_TABLE.", ".JBS_TABLE.", ".JBP_TABLE.") ON (".JBC_TABLE.".".JOB_TABLE."_id=".JOB_TABLE.".".JOB_TABLE."_id AND ".JBL_TABLE.".".JOB_TABLE."_id=".JOB_TABLE.".".JOB_TABLE."_id AND ".JBS_TABLE.".".JOB_TABLE."_id=".JOB_TABLE.".".JOB_TABLE."_id AND ".JBP_TABLE.".".JOB_TABLE."_id=".JOB_TABLE.".".JOB_TABLE."_id) WHERE ".JOB_TABLE."_display = '1' AND (".CAT_TABLE."_id IN (SELECT ".CAT_TABLE."_id FROM ".CAT_TABLE." WHERE ".CAT_TABLE."_display='1' ".$conds_cat.") AND ".LOC_TABLE."_id IN (SELECT ".LOC_TABLE."_id FROM ".LOC_TABLE." WHERE ".LOC_TABLE."_display='1' ".$conds_loc.")) GROUP BY ".JOB_TABLE.".".JOB_TABLE."_id ORDER BY ".JOB_TABLE."_rank DESC";
更新:感谢dwurf,后面的代码:
//echo $sql;
$res=$_Db->execute($sql);
$total = $_Db->numResults($res);
$displaylimit = $limit;
if ($total<$displaylimit+$start)
$displaylimit=$total-$start;
$sql .= " LIMIT ".$start.", ".$limit;
//echo $sql;
$res=$_Db->execute($sql);
if($_Db->numResults($res)>0) {
$co = 0;
while($row=$_Db->fetchAssoc($res)) {
$jobs[$co]["id"]=$row[JOB_TABLE."_id"];
$jobs[$co]["title"]=$row[JOB_TABLE."_title"];
$jobs[$co]["product"]=getCatLocSecTitle($_Db, PDT_TABLE, $row[PDT_TABLE."_id"]);
$jobs[$co]["salary"]=getCatLocSecTitle($_Db, SAL_TABLE, $row[SAL_TABLE."_id"]);
$co++;
}
}
答案 0 :(得分:2)
哇。
问题是您的查询是垃圾。数据库设计也可能需要一些工作。我认为PHP没有任何问题(除了过多的字符串操作),但我们只能看到它的一点点。
让我们整理你的SQL语句,这样我们就可以欣赏它的所有荣耀:
$sql =
"SELECT * FROM ".JOB_TABLE."
LEFT JOIN (
".JBC_TABLE.",
".JBL_TABLE.",
".JBS_TABLE.",
".JBP_TABLE.")
ON (
".JBC_TABLE.".".JOB_TABLE."_id=".JOB_TABLE.".".JOB_TABLE."_id
AND ".JBL_TABLE.".".JOB_TABLE."_id=".JOB_TABLE.".".JOB_TABLE."_id
AND ".JBS_TABLE.".".JOB_TABLE."_id=".JOB_TABLE.".".JOB_TABLE."_id
AND ".JBP_TABLE.".".JOB_TABLE."_id=".JOB_TABLE.".".JOB_TABLE."_id)
WHERE
".JOB_TABLE."_display = '1'
AND (".CAT_TABLE."_id IN
(SELECT ".CAT_TABLE."_id FROM ".CAT_TABLE." WHERE ".CAT_TABLE."_display='1' ".$conds_cat.")
AND ".LOC_TABLE."_id IN
(SELECT ".LOC_TABLE."_id FROM ".LOC_TABLE." WHERE ".LOC_TABLE."_display='1' ".$conds_loc."))
GROUP BY ".JOB_TABLE.".".JOB_TABLE."_id
ORDER BY ".JOB_TABLE."_rank DESC";
您的性能问题的根源很简单。如果未设置任何类别或位置,查询将检索作业表中每个作业的所有类别/位置的完整列表。我们说它与O(m * n)成比例,这是不好的。
提高性能的一种简单方法是在未设置位置/类别时完全删除该子句。好 也直接加入这些表,并检查类别是否应显示在where子句中。
$conds_cat = "";
$conds_loc = "";
$conds_sec = "";
$conds_sal = "";
if (isset($i["start"]) && $i["start"] > 0)
$start = $i["start"];
if (isset($i["limit"]) && $i["limit"] > 0)
$limit = $i["limit"];
$conds_cat = '';
$conds_loc = '';
if(isset($i["category"]) && $i["category"] != "")
$conds_cat = " AND ".CAT_TABLE.".".CAT_TABLE."_id ='".$i["category"]."'";
if(isset($i["location"]) && $i["location"] != "")
$conds_loc = " AND ".LOC_TABLE.".".LOC_TABLE."_id ='".$i["location"]."'";
$searchstring = "&category=".$i["category"]."&location=".$i["location"]."&limit=".$i["limit"];
$sql =
"SELECT
".JOB_TABLE.".*,
".JBC_TABLE.".*,
".JBL_TABLE.".*,
".JBS_TABLE.".*,
".JBP_TABLE.".*
FROM
".CAT_TABLE.",
".LOC_TABLE.",
".JOB_TABLE."
LEFT JOIN (
".JBC_TABLE.",
".JBL_TABLE.",
".JBS_TABLE.",
".JBP_TABLE.")
ON (
".JBC_TABLE.".".JOB_TABLE."_id=".JOB_TABLE.".".JOB_TABLE."_id
AND ".JBL_TABLE.".".JOB_TABLE."_id=".JOB_TABLE.".".JOB_TABLE."_id
AND ".JBS_TABLE.".".JOB_TABLE."_id=".JOB_TABLE.".".JOB_TABLE."_id
AND ".JBP_TABLE.".".JOB_TABLE."_id=".JOB_TABLE.".".JOB_TABLE."_id)
WHERE
".JOB_TABLE."_display = '1'
AND ".JOB_TABLE.".".CAT_TABLE."_id = ".CAT_TABLE.".".CAT_TABLE."_id
AND ".JOB_TABLE.".".LOC_TABLE."_id = ".LOC_TABLE.".".LOC_TABLE."_id
AND ".CAT_TABLE."_display = '1'
AND ".LOC_TABLE."_display = '1'
$conds_cat
$conds_loc
GROUP BY ".JOB_TABLE.".".JOB_TABLE."_id
ORDER BY ".JOB_TABLE."_rank DESC";
更新:修复了导致PHP错误或SQL结果不正确的两个错误。 更新2:修复了类别/位置过滤器中的错误
答案 1 :(得分:1)
我首先要确保它不能注射。您直接从用户获取输入并直接发送到数据库。唯一的检查是那里有东西。
PHP / MySQL有验证这一点的工具。我不知道你用什么函数来查询数据库,但我会假设它是标准的mysql库?
http://php.net/manual/en/function.mysql-real-escape-string.php
但也注意到顶部的红色警告,它已过时(虽然仍有效)