【问题标题】:Slow performance while fetching data获取数据时性能下降
【发布时间】:2017-12-13 08:34:19
【问题描述】:

我的网站运行速度非常慢,并且需要大量时间来加载数据。 加载数据需要 2-3 分钟。你能建议我如何让它快速吗?我正在从多个表中获取数据。该数据库有许多条目近25000个条目。

下面是我目前使用的代码。

<table class="table table-striped table-bordered bootstrap-datatable datatable">
<tbody>
  <?php // get all state
     $sql=" SELECT bm.bank_name,b.bank_ifsc,e.emp_id,e.emp_code,
                      e.first_name,e.middle_name,e.last_name,
                      e.active_status as emp_status,
                      e.account_no FROM tblemployee e 
        Left Join tblbank_mst bm  on bm.bank_id=e.fk_bank_id
        Left Join tblbank b  on b.bank_ifsc_id=e.fk_bank_ifsc_id 
        where e.del_status=0
          and e.role_id=4
          and e.is_admin=0 ";
     if($_SESSION["loggedin_role_id"]==2)
     {
     $sql.=" and  e.added_by=".$_SESSION["loggedin_emp_id"];
     }
     $sql.=" order by first_name";

     // echo $sql; exit;

     if(mysql_num_rows($result = mysql_query($sql))>0)
     { 
     while($row = mysql_fetch_array($result))
     { ?>
  <tr>
     <td><?php echo $row['emp_code'];?> </td>
     <td><?php echo $row['first_name'].' '.$row['middle_name'].' '.$row['last_name'];?> </td>
     <td><?php echo $row['bank_name'];?> </td>
     <td><?php echo $row['account_no'];?> </td>
     <td><?php echo $row['bank_ifsc'];?> </td>
     <td class="center">
        <?php if($row['emp_status']==1){ ?>
        <span class="label label-success">Active</span>
        <?php }else{?>
        <span class="label label-danger">Inactive</span>
        <?php }?>
     </td>
     <td class="center">
        <!--<a class="btn btn-success" href="#">
           <i class="halflings-icon white zoom-in"></i>  
           </a>-->
        <?php if($row['approve_status']==0){ ?>
        <a class="btn btn-info" href="edit_employee.php?emp_id=<?php echo $row['emp_id'];;?>">
        <i class="halflings-icon white edit"></i>  
        </a>
        <a class="btn btn-danger" href="#" onClick="ConfirmDelete(<?php echo $row['emp_id'];?>)">
        <i class="halflings-icon white trash"></i> 
        </a>
        <?php }else{ echo "--"; }?>
     </td>
  </tr>

【问题讨论】:

  • 你应该把这个发到Code Review
  • 您是否尝试过在查询中运行explain 以查看索引是否丢失?
  • 你为你的mysql表字段使用索引属性吗?
  • 请阅读此内容,并特别注意查询性能部分。 meta.stackoverflow.com/questions/271055/…edit您的问题提供更多详细信息。
  • 不要使用PHP的mysql_*接口。

标签: php mysql query-performance


【解决方案1】:

假设您的最大表是tblemployee,请尝试在WHERE 子句中提到的三列上创建复合索引,即:

 WHERE e.del_status=0 and e.role_id=4 and e.is_admin=0

你可以这样做

 CREATE INDEX emp_del_role_admin 
           ON tblemployee
              (del_status, role_id, is_admin);

为什么会有帮助?因为 MySQL 的查询计划器可以随机访问索引以查找与 WHERE 语句匹配的表的第一行,所以它可以顺序读取索引以查找其余匹配行。

当然,如果您的WHERE 过滤器匹配表中的数千行,您的页面仍然会很慢;加载、传输和渲染一个非常大的页面需要时间。

【讨论】:

  • 好吧,该索引可能适用于基本查询,但对于添加了and e.added_by 和/或order by 的查询效果不佳。
【解决方案2】:

如果您尝试一次显示 25000 个(或太多)条目:

这很慢,这很正常,您应该对结果进行分页:使用一些无限滚动插件来显示相同​​的内容并限制每个查询的结果 -EDIT : 或 DataTable 分页选项-。。 p>

如果你不是

首先你应该看看 slow queries ,在 my.cnf 文件中更改配置。 如果您的查询很慢,您可以通过在必须的地方添加INDEX 来优化您的查询。您应该使用EXPLAIN (documentation) 来帮助您执行此操作。 确保您已将外键声明为外键(bm.bank_id & e.fk_bank_id - b.bank_ifsc_id & e.fk_bank_ifsc_id),这将加快您的查询速度。在 e.role_id 之类的东西上添加索引也可以。

在这种情况下,只有您知道要添加哪个索引。

【讨论】:

    【解决方案3】:

    不要不要使用PHP的mysql_*接口;切换到 mysqli_* 或 PDO。

    添加两个复合索引:

    (del_status, role_id, is_admin, first_name)
    (del_status, role_id, is_admin, added_by, first_name)
    

    第一个处理您跳过额外的AND 的情况。

    以下模式可能有助于提高性能:更改

    ... bm.bank_name,
    ...
        Left Join  tblbank_mst bm  ON bm.bank_id=e.fk_bank_id
    

    ... ( SELECT bank_name FROM tblbank_mst WHERE bank_id=e.fk_bank_id
        ) AS bank_name,
    ...
    

    其他 LEFT JOIN 同上。

    【讨论】:

      【解决方案4】:

      请查看此答案,因为它可能对您有所帮助: https://stackoverflow.com/a/35757120/1276062

      简而言之,您应该检查这些列上是否有索引:

      • tblbank_mst.bank_id
      • tblemployee.fk_bank_id
      • tblbank.bank_ifsc_id
      • tblemployee.fk_bank_ifsc_id
      • tblemployee.del_status
      • tblemployee.role_id
      • tblemployee.is_admin
      • tblemployee.added_by
      • 名字

      如果索引没有帮助,您应该在查询上运行 EXPLAIN 并将结果发布到问题中

      【讨论】:

      • 创建许多单列索引通常有害,除非选择这些索引来加速特定查询。
      • 此外,“标志”(或其他具有低基数的值)上的单列索引基本上从不被使用。
      • @Kyborek - 我试图将主要提示消化成 mysql.rjweb.org/doc.php/index_cookbook_mysql 。这提供了更多提示:mysql.rjweb.org/doc.php/ricksrots
      • @Kyborek - 自己试验一下,找到(或创建)一个表,其中索引列的某些值出现在超过 30% 的行中。然后做EXPLAIN SELECT 看看索引在“应该”的时候没有被使用。
      • @Kyborek - 进一步实验,对SELECT 计时,并使用FORCE INDEX(..) 对查询计时。它可能表明索引使其变慢。 (有很多因素在发生,所以索引可能不会让它变慢。)
      猜你喜欢
      • 1970-01-01
      • 2021-12-03
      • 2021-02-21
      • 1970-01-01
      • 1970-01-01
      • 2018-08-20
      • 1970-01-01
      • 2013-05-10
      • 2014-08-22
      相关资源
      最近更新 更多