【问题标题】:PHP PDO SQL_CALC_FOUND_ROWS / FOUND_ROWS() strange issuePHP PDO SQL_CALC_FOUND_ROWS / FOUND_ROWS() 奇怪的问题
【发布时间】:2017-07-11 14:10:58
【问题描述】:

我找到了解决问题的方法,但这更多是关于为什么的问题。这是我的场景..

我在包含数千条记录的表上使用以下代码:

$stmt = $pdo->prepare("SELECT SQL_CALC_FOUND_ROWS * FROM ... LIMIT 10;");
$stmt->execute();
echo $pdo->query("SELECT FOUND_ROWS();")->fetchColumn(); # outputs 0

上面应该输出实际的记录数,但输出的是0。

现在,如果我在 SQL_CALC_FOUND_ROWS 查询的末尾添加一个尾随空格,它可以正常工作..

... LIMIT 10; ");

关于为什么会这样的任何想法??

更新

我尝试在不使用 PDO 的准备的情况下运行查询,它似乎也可以正常工作..

$stmt = $pdo->query("SELECT SQL_CALC_FOUND_ROWS * FROM ... LIMIT 10;");
echo $pdo->query("SELECT FOUND_ROWS();")->fetchColumn(); # works properly

我仍在尝试在较小的级别上重现这一点,以便其他人可以尝试一下,看看它是否会发生。

更新 2

我能重现此问题的最接近方法是使用以下代码:

# not working..
$stmt = $pdo->prepare("SELECT SQL_CALC_FOUND_ROWS * FROM `table` LIMIT 10");
$stmt->execute();
echo 'COUNT1: ' . $pdo->query("SELECT FOUND_ROWS()")->fetchColumn() . '<br>';

# working (notice the space before SELECT)..
$stmt = $pdo->prepare(" SELECT SQL_CALC_FOUND_ROWS * FROM `table` LIMIT 10");
$stmt->execute();
echo 'COUNT2: ' . $pdo->query("SELECT FOUND_ROWS()")->fetchColumn() . '<br>';

# output (from my database)
# COUNT1: 0
# COUNT2: 182020

这只发生在包含至少约 50 MB 数据的较大表上。我也无法在本地重现它,所以我认为这是服务器上的某种配置。这是我正在使用的..

  • Red Hat Enterprise Linux Server 7.1 版(迈坡)
  • 服务器版本:Apache/2.4.6
  • mysql Ver 14.14 Distrib 5.6.25,适用于 Linux (x86_64),使用 EditLine 包装器
  • PHP 5.4.16 (cli)

欢迎任何想法/想法!还想知道是否有人也可以成功重现这个问题(记得在更大的桌子上测试它)..

【问题讨论】:

  • 尝试var_dump($pdo-&gt;query("SELECT FOUND_ROWS();")-&gt;fetchColumn();) 而不是echo
  • 我猜这与 SQL 文本末尾包含的不必要的分号有关。为什么LIMIT 10后面有分号?
  • php.net/manual/en/pdo.error-handling.php 如果您不检查错误,则从那开始
  • 我同意,这很奇怪。我不希望查询中没有尾随空格会有所作为。我将假设在SELECT SQL_CALC_FOUND_ROWS and SELECT FOUND_ROWS()` 之间没有其他“隐藏”的 SELECT 运行。从提供的证据来看,当查询文本包含尾随空格时,很明显没有中间 SELECT。我认为我调试的下一步是打开 general_log 以捕获会话发出的每个 SQL 语句(最接近于模拟会话跟踪。)我讨厌跳上“这是一个错误”的潮流......跨度>

标签: php mysql pdo


【解决方案1】:

看来罪魁祸首是New Relic。我快速禁用了守护进程,看看这是否是问题所在,并且计数再次完美。

在这里找到我的答案:PHP PDO returning inconsistent results for SELECT FOUND_ROWS()

我决定在开头和结尾用一个空格来包装我的查询(只需要开头)。请注意,“\n”字符也可以使用。这样我就不必弄乱 New Relic 的配置了。

感谢新遗物!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    • 1970-01-01
    • 2018-05-04
    • 1970-01-01
    • 2017-03-10
    • 2020-07-28
    • 2015-12-20
    相关资源
    最近更新 更多