我将以下代码作为搜索员工并返回所需信息的大型Web应用程序的一部分。查询本身几乎没有时间完成并返回结果集。似乎需要一些改进的是我当前如何将结果编码为数组以使json_encode返回到前端。我没有关于如何改进代码的想法(因此我的问题在这里)。任何想法将不胜感激!
<?php
require_once("class.employee.php");
$employee = new Employee();
$employeeSearch = $employee->searchEmployees($_REQUEST['q']);
$employeeResults = array();
$row_array['id'] = $_REQUEST['q'];
$row_array['empName'] = $_REQUEST['q'];
$row_array['empBusinessTitle'] = '';
$row_array['empFacility'] = '';
array_push($employeeResults, $row_array);
while ($empInfo = $employeeSearch->fetchObject()) {
$row_array['id'] = $empInfo->empUserName;
$row_array['empName'] = ucwords($empInfo->empName);
$row_array['empBusinessTitle'] = $empInfo->empBusinessTitle;
$facilityName = $employee->getFacilityIDByAD($empInfo->empUserName);
$row_array['empFacility'] = isset($facilityName->facilityName) ? $facilityName->facilityName : '';
array_push($employeeResults, $row_array);
}
$ret['results'] = $employeeResults;
echo json_encode($ret);
Class Employee {
public function searchEmployees($query) {
try {
$dbh = new PDO($this->dbDSN, $this->dbUser, $this->dbPass);
$statement = $dbh->prepare("SELECT empID, CONCAT(empFirstName,' ',empLastName) as empName, empUserName, empBusinessTitle from $this->tblEmployeePeople where CONCAT(empfirstname,' ',emplastName) LIKE CONCAT('%',:query,'%') and empUserName != ''");
$statement->bindParam(':query', $query);
$statement->execute();
$dbh = null;
return $statement;
} catch (PDOException $e) {
echo $e->getMessage();
}
}
}?>
答案 0 :(得分:0)
首先,我将逐一删除您分配的所有数组参数。这需要CPU时间来添加到阵列。似乎你有一些复杂的循环,试着避免分配数组和许多循环执行到一个页面。
-------- UPDATE --------
试试这次更新:
$row_array = array(
'id' => $REQUEST['q'],
'empName' => $_REQUEST['q'],
'empBusinessTitle' => '',
'empFacility' = ''
);
while($empInfo = $employeeSearch->fetchObject()) {
$row_array[] = $empInfo;
}
array_push($employeeResults, $row_array);
然后只需通过数组$ row_array中各自的键请求结果。 正如雷已经在他的帖子中建议的那样,更新查询。他是对的。
答案 1 :(得分:0)
where子句中调用的函数会破坏您在这些字段上可能具有的任何索引。从性能角度来看,这是查询中最糟糕的部分。
CONCAT(empfirstname,' ',emplastName) LIKE CONCAT('%',:query,'%')
首先,为什么需要第二个CONCAT?就这样做
CONCAT(empfirstname,' ',emplastName) LIKE '%:query%'
但是,第一个Concat功能仍会达到指数突破惩罚。另外,为什么通配符喜欢?你可能想要一个完全相等的检查。
我会将传入的请求值“q”分解为名字的2个部分,然后将其传递给搜索函数。
在搜索功能中尝试此操作:
$nameArray = explode('',$query );
$firstname = $nameArray[0];
$lastname = $nameArray[1];
然后将您的查询更改为:
WHERE ( empfirstname LIKE ':firstname' AND emplastname = ':lastname' ) AND empUserName != ''
然后使用通配符添加绑定:
$statement->bindValue(':firstname', $firstname."%");
$statement->bindValue(':firstname', $lastname."%");