MySQL 有时错误地 returns 0 for count(*)
MySQL sometimes erroneously returns 0 for count(*)
我维护着一个对论坛话题进行分页的论坛。为了确定一个线程有多少页,我执行了查询
SELECT COUNT(*) AS `numrows`
FROM `forum_posts`
WHERE `thread_id` = '3004'
AND `deleted` = 0;
然后得到结果,除以每页的帖子数,然后四舍五入。上面的查询偶尔 return 结果为 0,我无法理解,这会导致分页中断。通常问题 "magically" 会在几分钟内自行修复,所以到目前为止,即使诊断它也是一段有趣的旅程。或者更确切地说,它可以持续几个小时,但似乎在我登录后几分钟就神奇地自行修复,试图看看发生了什么(尽管这可能是我的想象)。
当问题表现出 所有 此类查询 return 0 for numrows
,当它突然自行解决时,上述查询开始 return再次输入正确的值。
可能是什么导致了这个问题?
这个答案包含很多猜测,原来的问题没有包含足够的信息来确定这些。但是,此答案可能对更多读者有用。
The above queries occasionally return a result of 0 for no reason that I can fathom, which results in broken pagination.
当
时,您可以获得 0 条记录(或 COUNT(*) 查询中的 0 条记录)
- 没有行满足 WHERE 条件(例如,论坛主题中没有帖子)。
- 在 'seems to be bad' 查询和您发现错误的代码点之间有一个 error/exception。 (例如客户端无法连接到数据库服务器,错误被忽略)。
When the problem manifests all such queries return 0 for numrows, and when it resolves itself suddenly the above queries start returning the correct values again.
在这种特殊情况下,我敢打赌:已达到 mysql 中的最大连接数。
数据库访问层默默地忽略了错误,这导致可以将结果转换为数值 0。正如我们所知,0 除以任何值(0 除外)等于 0。
示例如下(复制粘贴者请勿使用此代码!)
try {
/**
Note for OO syntax only: If a connection fails an object is still returned.
To check if the connection failed then use either the
mysqli_connect_error() function or the
mysqli->connect_error property as in the preceding examples.
*/
$connection = new \mysqli('localhost', 'user', 'superSecretPass', 'database');
$query = 'SELECT COUNT(*) AS cnt FROM myTable WHERE this_flag IS NULL';
$result = $connection->query($connection, $query);
$itemCount = $result->fetchAssoc()['cnt'];
$result->close();
}
catch (\Exception $e) {
//Do nothing
}
$itemsPerPage = 15;
$sumPages = \ceil($itemCount / $itemsPerPage);
当上面的例子出现异常或者连接错误没有处理时:
- $itemCount 未定义
- $itemCount 将被视为 NULL
- NULL 将转换为 0
- 0/15 = 0
如果您想在底层处理错误(例如数据库访问)class,请以允许调用者收到有关 error/exception.[=13 的通知的方式进行=]
我们也遇到过这个问题。它也发生在 mysql 客户端(不是通过代码)。这似乎是 mysql 的错误。这是由索引合并交集
引起的
您可以在每个会话中将其关闭并尝试
设置会话 optimizer_switch="index_merge_intersection=off";
或者在您的 my.cnf
中进行全局设置
[mysqld]
optimizer_switch=index_merge_intersection=关闭
在此处提交错误报告
我维护着一个对论坛话题进行分页的论坛。为了确定一个线程有多少页,我执行了查询
SELECT COUNT(*) AS `numrows`
FROM `forum_posts`
WHERE `thread_id` = '3004'
AND `deleted` = 0;
然后得到结果,除以每页的帖子数,然后四舍五入。上面的查询偶尔 return 结果为 0,我无法理解,这会导致分页中断。通常问题 "magically" 会在几分钟内自行修复,所以到目前为止,即使诊断它也是一段有趣的旅程。或者更确切地说,它可以持续几个小时,但似乎在我登录后几分钟就神奇地自行修复,试图看看发生了什么(尽管这可能是我的想象)。
当问题表现出 所有 此类查询 return 0 for numrows
,当它突然自行解决时,上述查询开始 return再次输入正确的值。
可能是什么导致了这个问题?
这个答案包含很多猜测,原来的问题没有包含足够的信息来确定这些。但是,此答案可能对更多读者有用。
The above queries occasionally return a result of 0 for no reason that I can fathom, which results in broken pagination.
当
时,您可以获得 0 条记录(或 COUNT(*) 查询中的 0 条记录)- 没有行满足 WHERE 条件(例如,论坛主题中没有帖子)。
- 在 'seems to be bad' 查询和您发现错误的代码点之间有一个 error/exception。 (例如客户端无法连接到数据库服务器,错误被忽略)。
When the problem manifests all such queries return 0 for numrows, and when it resolves itself suddenly the above queries start returning the correct values again.
在这种特殊情况下,我敢打赌:已达到 mysql 中的最大连接数。 数据库访问层默默地忽略了错误,这导致可以将结果转换为数值 0。正如我们所知,0 除以任何值(0 除外)等于 0。
示例如下(复制粘贴者请勿使用此代码!)
try {
/**
Note for OO syntax only: If a connection fails an object is still returned.
To check if the connection failed then use either the
mysqli_connect_error() function or the
mysqli->connect_error property as in the preceding examples.
*/
$connection = new \mysqli('localhost', 'user', 'superSecretPass', 'database');
$query = 'SELECT COUNT(*) AS cnt FROM myTable WHERE this_flag IS NULL';
$result = $connection->query($connection, $query);
$itemCount = $result->fetchAssoc()['cnt'];
$result->close();
}
catch (\Exception $e) {
//Do nothing
}
$itemsPerPage = 15;
$sumPages = \ceil($itemCount / $itemsPerPage);
当上面的例子出现异常或者连接错误没有处理时:
- $itemCount 未定义
- $itemCount 将被视为 NULL
- NULL 将转换为 0
- 0/15 = 0
如果您想在底层处理错误(例如数据库访问)class,请以允许调用者收到有关 error/exception.[=13 的通知的方式进行=]
我们也遇到过这个问题。它也发生在 mysql 客户端(不是通过代码)。这似乎是 mysql 的错误。这是由索引合并交集
引起的您可以在每个会话中将其关闭并尝试 设置会话 optimizer_switch="index_merge_intersection=off";
或者在您的 my.cnf
中进行全局设置[mysqld] optimizer_switch=index_merge_intersection=关闭
在此处提交错误报告