使用pdo_sqlite时,SQL查询中的'LIKE'运算符非常慢

时间:2014-02-25 21:01:10

标签: php sql sqlite pdo sql-like

我发现使用pdo_sqlite(PHP 5.3或PHP 5.4),'SELECT'SQL查询中的'LIKE'运算符非常慢。
在sqlite3二进制文件中输入的相同查询更快。

示例代码:

<?php
    $bdd = new PDO('sqlite:./chaines_centre.db');
    $reponse = $bdd->prepare("select DateMonteeAuPlan, Debut, Fin, Statut from ReportJobs where NomJob = ? and NomChaine like 'DCLC257__' order by DateMonteeAuPlan DESC limit 20;");
    $reponse->execute($_GET['job']);
    while ($donnees = $reponse->fetch())
    {
        // whatever...
    }
    $reponse->closeCursor();
?>

以下是我制作的快速“基准”:

  1. pdo_sqlite测量的XDebug跟踪
  2. 带有'.timer on'
  3. 的SQLite二进制文件

    NomChaine like 'DCLC257__'
    ●pdo_sqlite:1.4521s✘
    ●sqlite3二进制:0.084s✔

    NomChaine like 'DCLC257%'
    ●pdo_sqlite:1.4881s✘
    ●sqlite3二进制:0.086s✔

    NomChaine = 'DCLC25736'
    ●pdo_sqlite:0.002s✔(我觉得它有点长,但速度很快)
    ●sqlite3二进制:0.054s✔


    我该如何改善这种情况?



    编辑:也许我过分关注'LIKE'运算符。

    <?php
    $bdd = new PDO('sqlite:./chaines_centre.db');
    
    
    $time_start = microtime(true);
    $reponse = $bdd->query("select DateMonteeAuPlan, Debut, Fin, Statut from ReportJobs where NomJob = 'NSAVBASE' and NomChaine like 'DCLC257%' order by DateMonteeAuPlan DESC limit 20;");
    $time_end = microtime(true);
    
    $time = $time_end - $time_start;
    echo "Situation 1 : $time second(s)<br><br>";
    // Output : 1.3900790214539 second(s)
    
    
    $time_start = microtime(true);
    $reponse = $bdd->query("select DateMonteeAuPlan, Debut, Fin, Statut from ReportJobs where NomJob = 'NSAVBASE' and NomChaine like 'DCLC257%' limit 20;");
    $time_end = microtime(true);
    
    $time = $time_end - $time_start;
    echo "Situation 2 : $time second(s)<br><br>";
    // Output : 0.0030009746551514 seconde(s)
    
    
    $time_start = microtime(true);
    $reponse = $bdd->query("select DateMonteeAuPlan, Debut, Fin, Statut from ReportJobs where NomJob = 'NSAVBASE' and NomChaine = 'DCLC25736' order by DateMonteeAuPlan DESC limit 20;");
    $time_end = microtime(true);
    
    $time = $time_end - $time_start;
    echo "Situation 3 : $time second(s)<br><br>";
    // Output : 0 seconde(s)
    ?>
    

    删除LIKE运算符或order by DateMonteeAuPlan后,查询将在预期时间内执行...
    太奇怪了。 O_O

1 个答案:

答案 0 :(得分:1)

你有没有机会在同一个脚本中运行PDO vs二进制文件(一个接一个)?如果你这样做,那么用二进制文件获得更好的结果是正常的,因为PDO在缓存为空时运行(因此它会击中光盘),而二进制文件从RAM获取数据。

对于你的第二个脚本,情况确实如此:第一个查询获得1.3秒以上,因为它也读取数据,而其余的则从RAM中获取数据。

有关详细信息,请参阅http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html#pragma-cache_size