MySQL有时会错误地为count(*)返回0

MySQL有时会错误地为count(*)返回0,mysql,count,Mysql,Count,我维护一个对论坛线程进行分页的论坛。为了确定一个线程有多少页,我执行查询 SELECT COUNT(*) AS `numrows` FROM `forum_posts` WHERE `thread_id` = '3004' AND `deleted` = 0; 然后得到结果,除以每页的帖子数,然后四舍五入。上面的查询偶尔会返回一个0的结果,原因我无法理解,这会导致分页中断。通常情况下,这个问题会在几分钟内“神奇地”自行修复,因此即使诊断到目前为止,这也是一个有趣的过程。

我维护一个对论坛线程进行分页的论坛。为了确定一个线程有多少页,我执行查询

SELECT COUNT(*) AS `numrows`
    FROM `forum_posts`
    WHERE `thread_id` = '3004'
    AND `deleted` = 0;
然后得到结果,除以每页的帖子数,然后四舍五入。上面的查询偶尔会返回一个0的结果,原因我无法理解,这会导致分页中断。通常情况下,这个问题会在几分钟内“神奇地”自行修复,因此即使诊断到目前为止,这也是一个有趣的过程。或者更确切地说,它可以持续数小时,但在我登录后几分钟,它似乎神奇地自行修复,试图看看发生了什么(尽管这可能是我的想象)

当问题出现时,所有此类查询对
numrows
返回0,当问题突然自行解决时,上述查询再次开始返回正确的值


是什么导致了这个问题?

这个答案包含很多猜测,原始问题没有包含足够的信息来确定这些猜测。然而,这个答案可能对其他读者有用

上面的查询偶尔会返回一个0的结果,原因我无法理解,这会导致分页中断

在以下情况下,您可以获得0条记录(或计数(*)查询中的0条记录)

  • 没有行满足WHERE条件(例如,论坛线程中没有帖子)
  • 在“似乎是坏的”查询和发现错误的代码点之间的某个地方存在错误/异常。(例如,客户端无法连接到数据库服务器,错误将被自动忽略)
  • 当问题出现时,所有此类查询都会为numrows返回0,当问题突然自行解决时,上述查询会再次开始返回正确的值

    在这种情况下,我打赌mysql中的最大连接数已经达到。 数据库访问层静默地忽略该错误,这将导致可以转换为数值0的结果。我们知道,0除以任何东西(0除外)等于0

    下面是一个示例(复制粘贴器:不要使用此代码!)

    在上述示例中发生异常或未处理连接错误时:

    • 未定义$itemCount
    • $itemCount将被视为NULL
    • NULL将被强制转换为0
    • 0/15=0

    如果您想处理底层(如数据库访问)类中的错误,请以允许调用方收到错误/异常通知的方式进行处理。

    我们也遇到了这个问题。它也发生在mysql客户端(不是通过代码)。这似乎是mysql的一个bug。它是由索引合并交集引起的

    您可以将其设置为每个会话,然后重试 设置会话优化器\u switch=“index\u merge\u intersection=off”

    或者在my.cnf中全局设置

    [mysqld] 优化器\开关=索引\合并\交叉点=关闭

    错误报告存档在这里


    导致此问题的原因是没有任何行满足
    where
    条件。事实上,这是有道理的,但事实并非如此:(根据定义,每个线程至少有一个post,并且无论post的数量多少,所有线程都会间歇性地出现这种情况。或者查询失败(并且您没有正确处理错误)。让服务器保留所做查询的日志。等待错误发生,然后查看日志以查看查询是否已更改。我没有说,您没有收到任何错误/警告。您收到了,并且您的db访问层可能会以静默方式捕获它们->查询结果将导致FALSE或NULL->将强制转换NULL/FALSE在计算页面的过程中设置为0->0/任何(除0之外)都是0。感谢您的回答。我采纳了您的建议来验证这是否是一个失败的查询,但似乎一切都是khosher:只有此查询返回错误的结果(呈现该页面时涉及的其他无数查询都没有失败),并且数据库中也没有产生警告。我在这里感到非常困惑…这个问题似乎在不同的会话中表现出来,但似乎在我从ssh会话登录到mysql时就消失了。也就是说,有人注意到一个线程有零页,我看,线程有零页,我ssh到服务器,线程仍然有零页,我记录在将表从MyISAM迁移到InnoDB后不久,我就开始注意到这个问题。作为第一步,您可以从这里开始(3条评论长文本表明,这是另一个问题。在评论中谈论类似的内容不是一个好主意。根据经验,当你不能在一条评论中提出你的补充内容时,这是一个新问题,或者你的原始问题没有提供解决问题所需的所有信息。我的建议是打开一个新问题,包括重现问题所需的所有步骤。原始问题是一个设计问题,新问题是一个与软件相关的问题。首先,我能够找到对我们也有影响的错误报告的参考。谢谢
    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);