PHP PDO 返回 SELECT FOUND_ROWS() 不一致的结果

标签 php mysql pdo percona mysqlnd

我对 PHP/PDO 和 MySQL 有疑问

当我使用 SQL_CALC_FOUND_ROWS 运行查询,然后选择 FOUND_ROWS() 时,80% 的时间它返回 0,其余时间 FOUND_ROWS 是准确的

我已将其简化为一个简单的测试循环,但这在我的开发服务器上运行良好,但在生产中测试用例存在不一致问题。

即使在生产中,从 MySQL 命令行运行相同的查询也能正常工作,因此这似乎是 PHP/PDO 问题

PHP 5.5.28 - 使用 mysqlnd 5.0.11-dev CentOS 6.6 上的 Percona Server 5.6.25-73.1-log(最终版)

有人可以帮忙吗?我已经尝试了我能想到的一切,但我正在抓狂

<?php
require_once "../consts.php";

$nolimit_query = "select SQL_CALC_FOUND_ROWS targetusers.u_id
  FROM 
    users targetusers 
    LEFT JOIN user_extra targetuserextra ON (targetuserextra.ue_userid = targetusers.u_id) 
    LEFT JOIN countries ON (c_id = targetusers.u_country) 
    LEFT JOIN cities ON (cities.ct_countryid = c_id and cities.ct_id = targetusers.u_city) 
    LEFT JOIN userimages ON (targetusers.u_primaryimage = userimages.ui_id and userimages.ui_userid = targetusers.u_id and userimages.ui_imagetype = 'P') 
  WHERE 
    (targetusers.u_deleted = 0) and 
    (targetusers.u_id NOT IN (19, 32, 115)) and 
    (targetusers.u_active = 1) and 
    (targetusers.u_confirmed=5) order by u_lastupdated DESC LIMIT 10, 10";

// already tried this soln suggested elsewhere -- defaults to off for my PHP anyway though
ini_set("mysql.trace_mode", 0);
ini_set("display_errors", 1);

// set up PDO connection
$dbh = new PDO(
    "mysql:host=" . Config::Get()->DB_SERVER . ";dbname=" . Config::Get()->DATABASE_NAME . ";charset=utf8", 
    Config::Get()->DB_USERNAME, 
    Config::Get()->DB_PASSWORD
);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->setAttribute(PDO::ATTR_PERSISTENT, false);

echo $dbh->getAttribute(PDO::ATTR_CLIENT_VERSION) . "<br>";
echo $dbh->getAttribute(PDO::ATTR_DRIVER_NAME) . "<br>";
echo $dbh->getAttribute(PDO::ATTR_SERVER_INFO) . "<br>";
echo $dbh->getAttribute(PDO::ATTR_SERVER_VERSION) . "<br><br>";

echo date("r") . "<br>";
for ($i=0; $i<5; $i++)
{
    // run query above
    $stmt = $dbh->prepare($nolimit_query);
    if ($stmt === FALSE)
    {
        die($stmt->errorInfo());
    }

    // get result set 
    if (($result = $stmt->execute()) === TRUE)
    {
        $a = $stmt->fetchAll(PDO::FETCH_ASSOC);
        $stmt->closeCursor();
        $stmt = NULL;

        // this query returns inconsistent results (80% of the time it returns 0!)
        $b = $dbh->query("SELECT FOUND_ROWS() as cnt")->fetch(PDO::FETCH_ASSOC);
        echo "FOUND ROWS = " . $b["cnt"] . "<br>";      
    }
}

该脚本的输出如下。

请注意,5 个循环中只有 2 个返回 FOUND_ROWS 的正确值,其他 3 个返回为 0

mysqlnd 5.0.11-dev - 20120503 - $Id: 15d5c781cfcad91193dceae1d2cdd127674ddb3e $
mysql
Uptime: 1857223 Threads: 1 Questions: 4446069 Slow queries: 32 Opens: 465 Flush tables: 1 Open tables: 403 Queries per second avg: 2.393
5.6.25-73.1

Fri, 04 Sep 2015 12:01:10 +0100
FOUND ROWS = 0
FOUND ROWS = 0
FOUND ROWS = 59836
FOUND ROWS = 0
FOUND ROWS = 59836

最佳答案

问题已解决。事实证明,NewRelic 应用程序监控守护进程或扩展程序干扰了 FOUND_ROWS() 的结果

这太糟糕了:(

禁用扩展,FOUND_ROWS 再次万无一失

关于PHP PDO 返回 SELECT FOUND_ROWS() 不一致的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32396703/

相关文章:

php - 在 php 中填充选择标签

php - PDO 为带有命名占位符的 INSERT 和 ON DUPLICATE KEY UPDATE 准备语句

php - 使用 PHP/MYSQL 进行基于对话的消息传递?

javascript - $_POST 未显示当前选项

php - XPath 直到下一个标记

mysql - 创建表时根据其他两列计算第三列

mysql 查询耗时超过 30 秒

mysql - SQL LEFT JOIN 只有最新的右列条目?

php - 为什么我的 else 语句运行代码两次

java - 如何促进服务器上的 php 脚本与另一台服务器上正在运行的 Java 应用程序之间的通信?