0

我的网站www.guidedsolutions.co.uk是前段时间建立的,我对 php 不太了解,但是当我输入搜索条件时,即苏格兰的医疗销售工作,搜索结果加载速度非常快,但是当我点击搜索所有结果页面加载非常缓慢,有时甚至不加载。这是它的直接链接: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++;

    }
}
4

2 回答 2

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:修复了类别/位置过滤器中的错误

于 2013-01-16T11:11:30.947 回答
1

我会首先确保它不可注射。你直接从用户那里获取输入并直接发送到数据库。唯一的检查是那里有东西。

PHP / MySQL 有验证这一点的工具。我不确定您使用什么函数来查询数据库,但我会假设它是标准的 mysql 库?

http://php.net/manual/en/function.mysql-real-escape-string.php

但还要注意顶部的红色警告,它已过时(尽管仍然有效)

于 2013-01-16T11:47:36.580 回答