PHP - 从MySQL数据库循环结果时加载页面缓慢

时间:2018-01-24 01:39:01

标签: php mysql pageload page-load-time

我有php代码从MySQL数据库中获取结果 - 玩具的名称(在toys表中)用于users玩具和独特用户的数量并显示在网页上。

玩具的名称可以是单个单词或单词组合。我们希望从toys获取这些结果,其中toys_text字段包含来自words表的单词组合的所有单词(示例 - 如果words表具有名为{{的条目1}} - blue car表格bluecar应该出现在toystoys_text字段中以进行匹配。随着时间的推移,数据库随着玩具的添加而被添加,玩具被删除已经过时。

结果页面加载速度非常慢,在GT-metrix测试中大约需要10秒钟。谷歌分析说我的代码存在问题。我的代码有子查询,如下所示 -

<?php
$WordQ = $db->query("SELECT * FROM words ORDER BY `words`.`words` ASC");

$i = 1;
    while($row = $WordQ->fetch(PDO::FETCH_ASSOC)){                      
        $Word = $row['words'];
        $WordsArr = explode(" ", $row['words']);

        $query = "";
        if(count($WordsArr) > 1){
          $query = "SELECT t_id,name,toys_text FROM toys WHERE toys_text 
        LIKE '%".implode("%' AND toys_text LIKE '%", $WordsArr)."%'";
        }else{
            $query = "SELECT t_id,name,toys_text FROM toys WHERE toys_text 
        LIKE '%$WordsArr[0]%'";
                    }
        $countIds = array();
        $countNames = array();
        $Data = $db->query($query);
        while($data = $Data->fetch(PDO::FETCH_ASSOC)){
        $countIds[] = $data['t_id'];
        $countNames[] = $data['name'];
                    }                       
        ?>                  
          <tr>
            <td><?php echo $i;?></td>
            <td><?php echo $row['words'];?></td>
            <td><a href="showtoys.php?word=<?php echo urlencode($Word); ?
            >" target="_blank"><?php echo count(array_unique($countIds)); ?>
            </a></td>
            <td><a href="showtoys.php?word=<?php echo urlencode($Word); ?
            >" target="_blank"><?php echo count(array_unique($countNames)); 
            ?></a></td>
          </tr>
            <?php $i++;} ?> 

我尝试删除子查询但页面加载缓慢。请指导如何加快页面加载速度。以下是没有子查询的代码 -

<?php
$query = "SELECT * FROM words ORDER BY `words`.`words` 
ASC";
$result = mysqli_query($con, $query);

$i = 1;         
    while($row = mysqli_fetch_array($result)){                      
        $Word = $row['words'];
        $WordsArr = explode(" ", $row['words']);
        $query = "";
           if(count($WordsArr) > 1){
               $query1 = "select COUNT(*) as 'count', COUNT(DISTINCT 
               t.name) AS 'cnt' from toys t WHERE toys_text LIKE '%".implode("%' AND 
               toy_text LIKE '%", $WordsArr)."%'";
            }else{
            $query1 = "select COUNT(*) as 'count', COUNT(DISTINCT t.name) AS 
           'cnt' from toys t WHERE 
            toys_text LIKE '%$WordsArr[0]%'";
            }               
            $Data1 = mysqli_query($con, $query1);
            $total1 = mysqli_fetch_assoc($Data1);                       
                ?>                  
            <tr>
              <td><?php echo $i;?></td>
              <td><?php echo $row['words'];?></td>
              <td><a href="showtoys.php?word=<?php echo 
              urlencode($Word); ?>" target="_blank"><?php echo 
              $total1['count']; ?></a></td>
              <td><a href="showtoys.php?keyword=<?php echo urlencode($Word); 
              ?>" target="_blank"><?php echo $total1['cnt']; ?></a></td>                    
            </tr>
                <?php $i++;} ?> 

这是我的MySQL表结构 -

字词:

S.No名称类型

  1. id Primary int(11)

  2. 字varchar(60)

    示例 - 白色汽车,气球,蓝色巴士

  3. 输入enum('words','phrase')

  4. 玩具:

    S.No。名称类型

    1. t_id主要bigint(20)

    2. toys_text FULLTEXT Index varchar(255)

    3. user_id BTREE Index bigint(20)

    4. 名称BTREE索引字符(20)

    5. Mysql是带有InnoDB存储的10.1.30-MariaDB。

      修改

      假设我在words表中,玩具名为little blue car。那么真正的比赛将是 - 我有little car,即blue。 我的little car blue颜色非常快。

      错误匹配将是 -

      我有一辆小车。 我的小车非常好。

      意味着所有单词都应出现在toys_text字段中以进行真正的匹配。

      我将查询更改为

      if(count($WordsArr) > 1){ 
      $query1 = "select COUNT() as 'count', 
      COUNT(DISTINCT t.name) AS 'cnt' from toys t WHERE MATCH (toys_text) AGAINST 
      ('".implode("'+'", ($WordsArr))."' IN BOOLEAN MODE)"; 
      }else{ 
      $query1 = "select COUNT() as 'count', COUNT(DISTINCT t.name) AS 'cnt' from 
      toys t WHERE MATCH (toys_text) AGAINST ('%$WordsArr[0]%')"; 
      

      现在,它为具有高计数和单词组合的单词提供0计数。这些单词不在Mysql的停止列表中。这是FULLTEXT搜索的一些限制吗?

4 个答案:

答案 0 :(得分:0)

我认为问题来自执行sql请求的PHP循环。所以为了减少你不应该做很多要求但是严格的最低要求的时间。在你的情况下,找到干净的方式有点难,但应该有一个!

通过使用sql Substring函数创建“玩具”表的所有单词(逐个)的视图可能有一种方法。然后子查询函数不是“喜欢”而是简单的“=”,这要快得多。 https://mariadb.com/kb/en/library/create-view/

答案 1 :(得分:0)

我建议使用存储过程让您的查询更快,因为您使用过  一个while循环,然后你有另一个查询。如果你只是调用一个过程比在php中构建查询更快。

尝试检查此链接以获取参考:https://dev.mysql.com/doc/refman/5.7/en/stored-routines.html

我向您保证会进行顺畅的查询。

如果你只需要计算那些包含这个词的玩具的数量 我建议只使用Join在while循环之前的第一部分中查询所有内容然后对它们进行计数,然后将它们分组。

$stringWord= str_replace(' ', '%', $WordsArr);

$query1 = "call toysQuery(".$stringWord.")";

然后在你的过程参数中使用varchar。

答案 2 :(得分:0)

您正在循环中从SQL语句的输出生成并运行SQL。只需在查询之间进行连接,一次往返数据库,一次循环显示结果。

答案 3 :(得分:0)

正如@Sammitch所建议的,使用foreach循环在布尔模式下使用MATCH()更改查询。现在,页面正在加载三分之一,大约3秒钟。

这是我的代码 -

<?php
$query = "SELECT * FROM words ORDER BY `words`.`words` 
ASC";
$result = mysqli_query($con, $query);

$i = 1;            
while($row = mysqli_fetch_array($result)){                        
    $Word = $row['words'];
    $WordsArr = explode(" ", $row['words']);
    $query = "";

       if(count($WordsArr) > 1){
          foreach ($WordsArr as $value) {
                    $value1='';
                    $value1 .= " +"."(".$value."*".")";
                    }
           $query1 = "select COUNT(*) as 'count', COUNT(DISTINCT 
           t.name) AS 'cnt' from toys t WHERE MATCH (toys_text) AGAINST 
          ('$value1' IN BOOLEAN MODE)";
        }else{
        $query1 = "select COUNT(*) as 'count', COUNT(DISTINCT t.name) AS 
       'cnt' from toys t WHERE 
        MATCH (toys_text) AGAINST ('$WordsArr[0]* IN BOOLEAN MODE')";
        }               
        $Data1 = mysqli_query($con, $query1);
        $total1 = mysqli_fetch_assoc($Data1);                     
            ?>                  
        <tr>
          <td><?php echo $i;?></td>
          <td><?php echo $row['words'];?></td>
          <td><a href="showtoys.php?word=<?php echo 
          urlencode($Word); ?>" target="_blank"><?php echo 
          $total1['count']; ?></a></td>
          <td><a href="showtoys.php?keyword=<?php echo urlencode($Word); 
          ?>" target="_blank"><?php echo $total1['cnt']; ?></a></td>                   
        </tr>
            <?php $i++;} ?>