2012-05-15 68 views
2

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

<?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(); 
?> 
+1

如果您使用的是准备好的语句,您为什么需要动态创建查询? –

+0

,因为我不知道用户将提交多少条款,这就是为什么我爆炸我的$ _GET变量以逗号分隔不同条款 假设用户想要搜索包含单词php和asp的结果... –

+2

call_user_func_array比显式调用方法要慢 - 但不太可能对代码做出任何显着的改变,因为你只调用它两次。使用可变数量的UNION选择可能会比使用可能在页面加载时间增加1ms的函数更加昂贵/有问题。 – AD7six

回答

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像/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 profiling,看看你的代码是花钱的时候
  • Webgrind是一个易于安装的XDebug看到轮廓输出的手段。

不要浪费你的时间来优化0.01%

call_user_func_array确实有使用成本,这就是为什么code like this存在。但是这种差异真的很微不足道(尤其是在问题中UNION超级查询的情况下),除非你调用了数百次以上。专注于对应用程序性能影响最大的事物,而不是以任何方式完全没有可衡量的差异的事物。

+0

我没有意识到UNION querys是如此昂贵,我想我有很多要了解mysql,无论如何,这些信息已经非常有帮助谢谢。 –