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、それらの 1 つではありません。

クエリを見てください

これは、作成している種類のクエリです。

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 個のフルテキスト インデックス クエリになります。それは本当にあなたが望むものですか?そうかもしれませんが、たとえば、誰かが既知のハビリダードを検索する場合は、次のようにする方がはるかに効率的です。

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 に答える