搜索所有php加载非常慢?

时间:2013-01-16 09:35:13

标签: php mysql

我的网站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++;

    }
}

2 个答案:

答案 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

但也注意到顶部的红色警告,它已过时(虽然仍有效)