【问题标题】:SQL_CALC_FOUND_ROWS / FOUND_ROWS() does not work in PHPSQL_CALC_FOUND_ROWS / FOUND_ROWS() 在 PHP 中不起作用
【发布时间】:2015-06-17 21:51:35
【问题描述】:

我在 Mysql SELECT 语句中使用SQL_CALC_FOUND_ROWS 来获取我的 SELECT 在没有 LIMIT 子句的情况下返回的行数。

$sql = new mysqli('localhost', 'root', '');
$sql->select_db('mysql');
$s1 = $sql->query('select SQL_CALC_FOUND_ROWS * from db limit 0, 3');
$s2 = $sql->query('select FOUND_ROWS()');
if($row = $s2->fetch_row()) printf('%d/%d', $s1->num_rows, $row[0]);

在我的 WinXP 开发站上,它在几周内每次都返回 3/0。当我从我的站使用另一个 MySQL 服务器时,它也返回 3/0。 在另一台 PC 上,相同的代码运行良好,并返回正确的数字(例如,如果我在 mysql.db 表中有 17 条记录,则为 3/17)。每台 XP PC 都有相同的 PHP/Mysql 版本,过去在我的 PC 上运行良好 将 Mysql Query Browser 与相同的 SQL 查询一起使用,我得到了正确的数字。

谁能给我一个解决方案的想法,而无需重新安装所有?

抱歉,我之前的请求非常不清楚。

【问题讨论】:

  • 你能包含你的PHP代码吗?您确定要使用与用于查询的数据库连接资源相同的数据库连接资源来请求计数吗?
  • 您的问题缺少产生的错误和您正在使用的代码,不赞成。
  • @PaulDixon 谢谢保罗!在我们的 .net 代码中,我们总是在创建新的连接,所以我一看到您的评论,就知道这一定是我的问题。
  • @JasonFuller - 可能想要解决这个问题。每个查询的新连接都非常昂贵。

标签: php mysql


【解决方案1】:

谢谢。

当我在 mysql 命令行上运行与您的示例类似的东西时,它会起作用;但是从php运行它,它失败了。第二个查询必须“了解”第一个查询,所以我认为链接两个查询的持久性/内存被 php 搞砸了。

(事实证明,Wordpress 使用这种类型的查询来进行分页 - 所以我们更大的问题是,当我们迁移到 php 5.2.6 时,wordpress 安装中的分页突然停止工作......最终将其追踪到FOUND_ROWS())。

只是为了为将来可能遇到此问题的人发帖...对我来说,这是 php 设置“mysql.trace_mode” - 这在 5.2.6 中默认为“on”而不是“off”以前,并且由于某种原因阻止 FOUND_ROWS() 工作。

作为“修复”,我们可以将它放在每个 php 页面中(实际上,在一个常见的“包含”中):

ini_set("mysql.trace_mode", "0");

或将其添加到 .htaccess:

php_value mysql.trace_mode "0"

再次感谢, 杰瑞

【讨论】:

    【解决方案2】:

    您是否使用允许多个查询的 MySQL 查询方法。

    来自 MySQL 文档。

    要获取此行数,请在 SELECT 语句中包含 SQL_CALC_FOUND_ROWS 选项,然后调用 FOUND_ROWS()

    例子:

    mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
        -> WHERE id > 100 LIMIT 10;
    mysql> SELECT FOUND_ROWS();
    

    也只是为了好玩,关于FOUND_ROWS()的使用here.的竞争条件有一个很好的讨论

    【讨论】:

    • 竞争条件是意料之中的,但我怀疑对于这样的操作来说并不是那么重要。即便如此,还是要注意这一点。
    【解决方案3】:

    另一种方法是使用 PHP 手册中所述的 mysqli_multi_query,方法是传递包含 SQL_CALC_FOUND_ROWS 和 FOUND_ROWS 的两个查询,并用分号分隔

    <?php
    $mysqli = new mysqli("localhost", "my_user", "my_password", "world");
    
    /* check connection */
    if (mysqli_connect_errno()) {
        printf("Connect failed: %s\n", mysqli_connect_error());
        exit();
    }
    
    $query  = "SELECT SQL_CALC_FOUND_ROWS * FROM db limit 0, 3;";
    $query .= "SELECT FOUND_ROWS()";
    
    /* execute multi query */
    if ($mysqli->multi_query($query)) {
        do {
            /* store first result set */
            if ($result = $mysqli->store_result()) {
                while ($row = $result->fetch_row()) {
                    printf("%s\n", $row[0]);
                }
                $result->free();
            }
            /* print divider */
            if ($mysqli->more_results()) {
                printf("-----------------\n");
            }
        } while ($mysqli->next_result());
    }
    
    /* close connection */
    $mysqli->close();
    ?>
    

    【讨论】:

    • 我认为它必须是 SELECT FOUND_ROWS()
    【解决方案4】:

    最快的解决方案是像这样子查询您的实际查询:

    SELECT SQL_CALC_FOUND_ROWS * FROM (SELECT whatever FROM whatever WHERE whatever LIMIT whatever) ax; 
    select FOUND_ROWS();
    

    现在您将得到正确的结果。我认为主要原因是SQL_CALC_FOUND_ROWS 主要跟踪找到的行(即没有LIMITS)而不是返回的行。

    【讨论】:

      【解决方案5】:

      我有同样的问题。解决方案很愚蠢,我使用的是$wpdb-&gt;query 而不是$wpdb-&gt;get_var。所以你想做

      $wpdb->get_var('select FOUND_ROWS()');
      

      如果您使用的是 WordPress

      【讨论】:

        【解决方案6】:

        嗯,这是与 php 5.2.6 捆绑在一起的 mysql php 扩展的问题。 Mysqli 运行良好,还有另一个 php 版本。 很抱歉有噪音和不清楚的问题。

        如果你有同样的问题,我的建议是重新安装 PHP 或更改版本。

        【讨论】:

          猜你喜欢
          • 2017-07-11
          • 2017-03-10
          • 1970-01-01
          • 1970-01-01
          • 2017-04-06
          • 1970-01-01
          • 2018-05-04
          • 2012-03-06
          • 1970-01-01
          相关资源
          最近更新 更多