【问题标题】:How to use MySQL Found_Rows() in PHP?如何在 PHP 中使用 MySQL Found_Rows()?
【发布时间】:2010-08-10 21:59:50
【问题描述】:

由于性能问题,我尽量避免使用 Count()。 (即 SELECT COUNT() FROM Users)

如果我在 phpMyAdmin 中运行以下命令,就可以了:

  SELECT SQL_CALC_FOUND_ROWS * FROM Users;
  SELECT FOUND_ROWS();

它将返回行数。即用户数。

但是,如果我在 PHP 中运行,我不能这样做:

  $query = 'SELECT SQL_CALC_FOUND_ROWS * FROM Users;
    SELECT FOUND_ROWS(); ';
  mysql_query($query);

似乎 PHP 不喜欢传入两个查询。那么,我该怎么做呢?

【问题讨论】:

  • 这就是我们所说的“过早优化”...
  • 顺便说一句,您不能使用mysql_query() 发送2 个查询。您必须单独发送每个查询。如果您想一次发送多个数据库,请使用另一个数据库接口。

标签: php mysql sql-calc-found-rows


【解决方案1】:

只有这段代码对我有用,所以我想为你分享。

$Result=mysqli_query($i_link,"SELECT SQL_CALC_FOUND_ROWS  id From users LIMIT 10"); 
$NORResult=mysqli_query($i_link,"Select FOUND_ROWS()"); 
$NORRow=mysqli_fetch_array($NORResult); 
$NOR=$NORRow["FOUND_ROWS()"]; 
echo $NOR;

【讨论】:

    【解决方案2】:

    这是一种简单的方法,对我有用:

    $query = "
    SELECT SQL_CALC_FOUND_ROWS * 
    FROM tb1
    LIMIT 5";
    
    $result = mysqli_query($link, $query);
    
    $query = "SELECT FOUND_ROWS() AS count";
    $result2 = mysqli_query($link, $query);
    
    $row = mysqli_fetch_array($result2);
    
    echo $row['count'];
    

    【讨论】:

      【解决方案3】:

      它的两个查询:

      $query = 'SELECT SQL_CALC_FOUND_ROWS * FROM Users';
      mysql_query($query);
      $query = 'SELECT FOUND_ROWS()';
      mysql_query($query);
      

      每个 mysql_query 调用 PHP 只能发出一个查询

      【讨论】:

      • 是的 murvinlai,您需要执行 2 个查询。但是在 PHP 中你需要看到你可以有 N 个用户在线发送请求,所以如果其他 SQL 执行发生在同一个连接中,你的 FOUND_ROWS() 不起作用,你需要按照你的指令在同一连接和顺序。一种方法是在一个隔离的连接中执行命令,您从您的结构中获取一个连接,执行查询并发布到结构。
      【解决方案4】:

      SQL_CALC_FOUND_ROWS 仅在您使用LIMIT 子句时有用,但仍想知道如果没有LIMIT 会找到多少行。

      想想这是如何工作的:

      SELECT SQL_CALC_FOUND_ROWS * FROM Users;
      

      您正在强制数据库检索/解析表中的所有数据,然后将其丢弃。即使您不打算检索任何行,数据库服务器仍会开始从磁盘中提取实际数据,假设您需要这些数据。

      从人类的角度来说,你买了超级杂货店的所有东西,但是除了收银台旁边的那包口香糖之外,你把所有东西都扔掉了。

      而,做:

      SELECT count(*) FROM users;
      

      让数据库引擎知道,虽然您想知道有多少行,但您不能不关心实际数据。在大多数智能 DBMS 上,引擎可以从表的元数据中检索此计数,或者通过表的主键索引进行简单的运行,而无需接触磁盘上的行数据。

      【讨论】:

      • 完全正确,但是如果我已经对我的用户进行了分组并且想计算现在有多少组要按这些组进行分页?这是一个简单的例子,我在现实生活中有更复杂的群体。
      • 我有一个包含limit 子句的查询。现在我想使用found_rows() 选择有限的数据和匹配结果的总数。如何?我想要类似this (这不起作用)
      • 是的,这个用例当然是SELECT SQL_CALC_FOUND_ROWS * FROM users LIMIT 10;,然后是SELECT FOUND_ROWS();,在这种情况下,RDBMS 正在计算总预限制。优点是不必为计数和读取重写整个查询。
      【解决方案5】:

      使用“联合”和空列:

      $sql="(select sql_calc_found_rows tb.*, tb1.title
            from orders tb
                 left join goods tb1 on tb.goods_id=tb1.id
            where {$where}
            order by created desc
            limit {$offset}, {$page_size})
            union
            (select found_rows(), '', '', '', '', '', '', '', '', '')
           ";
      $rs=$db->query($sql)->result_array();
      $total=array_pop($rs);
      $total=$total['id'];
      

      【讨论】:

        【解决方案6】:

        这是一个常见的误解,认为 SQL_CALC_FOUND_ROWS 的性能优于 COUNT()。看看 Percona 人的这个比较:http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/

        回答您的问题:每次 mysql_query 调用只允许一个查询,如手册所述:mysql_query() sends a unique query (multiple queries are not supported)

        使用ext/mysqli 作为 MySQL 扩展时支持多个查询:

        http://www.php.net/manual/en/mysqli.multi-query.php

        【讨论】:

          【解决方案7】:

          您真的认为从表中选择所有行比计算它们更快吗?
          Myisam 在表的元数据中存储了许多记录,因此 SELECT COUNT(*) FROM 表不必访问数据。

          【讨论】:

            猜你喜欢
            • 2012-12-20
            • 1970-01-01
            • 2018-01-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多