4

我正在使用 mysqli 和准备好的语句为我的数据库编写一个简单的搜索引擎,我目前正在使用 call_user_func_array 来动态创建我的查询。我的问题是:使用 mysqli 是否有更快或更好的方法来做到这一点?这是我的代码:

<?php 
session_start();
require('../../../scripts/bkfunctions.php');
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Content-type: application/json');

//////////////////
$resultParameters = array();
$paramsArr =array();
$results = array();




////DB OPEN//////////////////////////////////////////
$conn = dbConnect("ITbunker");
$paramsArr = explode(",", $_GET['paramsQuery']);
$qStr="";
$bindParams = array('s');

    ////////////////////////////////////
    foreach ($paramsArr as $n=>$k) {

            if ($n==0) {
            $qStr = "SELECT * FROM trabajosEnSubasta WHERE MATCH(titulo, descripcion, habilidades) AGAINST (?)";
            }
            else {
            $qStr .= " UNION SELECT * FROM trabajosEnSubasta WHERE MATCH(titulo, descripcion, habilidades) AGAINST (?)";
            $bindParams[0] .= 's';
            }
            array_push($bindParams, $k);
    }
    ///////////////////////////////////////

    ///Preparar query y ejecutar
    $stmt = $conn->prepare($qStr);
    call_user_func_array(array($stmt, 'bind_param'), makeValuesReferenced($bindParams));
    $stmt->execute();

/////////////////////////////////////////////////////////////////////////////////////////*

$meta = $stmt->result_metadata();  

    while ($campo = $meta->fetch_field() ) {
    $resultParameters[] = &$row[$campo->name];
    }
    call_user_func_array(array($stmt, 'bind_result'), $resultParameters);

    $i=0;
    while ( $stmt->fetch() ) {  
        $i++;
        foreach( $row as $key => $val ) {
        $results["resultado$i"][$key] = $val;
        }  
    }


echo json_encode($results);
///////////////////////////////////////////////////

$conn->close();
?>
4

1 回答 1

4

您的问题有很多要解决的问题 - 而call_user_func_array不是其中之一。

查看您的查询

这是您正在构建的查询类型:

SELECT
    * 
FROM 
    trabajosEnSubasta 
WHERE 
    MATCH(titulo, descripcion, habilidades) AGAINST (?)
UNION 
    SELECT
        * 
    FROM 
        trabajosEnSubasta 
    WHERE 
        MATCH(titulo, descripcion, habilidades) AGAINST (?)
UNION 
    SELECT
        ...

而且..它引出了你为什么要这样做的问题。这在功能上是相同的,并且执行起来可能要快得多:

SELECT
    * 
FROM 
    trabajosEnSubasta 
WHERE 
    MATCH(titulo, descripcion, habilidades) AGAINST (?)
    OR
    MATCH(titulo, descripcion, habilidades) AGAINST (?)
    OR
    ...

看看你的逻辑

$paramsArr = explode(",", $_GET['paramsQuery']);

因此,请求 url like/foo?paramsQuery=a,b,c,d,e,f,g,h,i,j当前将触发 10 个表联合查询,如果您更新查询语法,那将是 10 个全文索引查询。这真的是你想要的吗?可能是 - 但例如,如果有人搜索已知的 habilidad,这样做会更有效率:

SELECT
    trabajosEnSubasta.*
FROM
    trabajosEnSubasta
LEFT JOIN
    habilidades_map ON habilidades_map.trabajo_id = trabajosEnSubasta.id
WHERE
    habilidades_map.habilidad = "known habilidad"

全文索引查询起来相对昂贵,并且不应该是您搜索数据的唯一方法。

分析您的代码

我不得不假设您正在询问,call_user_func_array因为您的代码执行速度很慢。不要猜测代码中的问题出在哪里,并找出问题所在。

  • 使用explain查看您的查询在做什么
  • 使用xdebug 分析来查看你的代码在哪里花费它的时间
  • Webgrind是一种易于安装的查看 xdebug 配置文件输出的方法。

不要浪费时间优化 0.01%

call_user_func_array确实有使用成本,这就是存在这样的代码的原因。但是差异确实非常微不足道(尤其是考虑到问题中的超重 UNION 查询),除非您将其称为数百次以上。专注于对您的应用程序性能影响最大的事情,而不是那些绝对无法以某种方式产生可衡量差异的事情。

于 2012-05-16T10:33:27.983 回答