是啥导致 MySQL 基数减少?

Posted

技术标签:

【中文标题】是啥导致 MySQL 基数减少?【英文标题】:What causes MySQL cardinality to decrease?是什么导致 MySQL 基数减少? 【发布时间】:2014-07-17 21:11:23 【问题描述】:

在我们的生产 mysql 系统中,我们有一些查询通常需要不到 2 秒的时间来执行,但有时它们会运行超过一分钟。每次这些查询中的一个长时间运行时,我们都会检查索引并发现基数在同一​​个 VARCHAR(25) 字段上下降。我们将 MySQL 作为具有多个从属服务器的主集群运行,我们会发现在那个慢速系统上的基数已经降低,但在所有其他服务器上该值将保持高位。当价值下降时,它将从大约 20k-30k(高价值)下降到只有几百。运行 ANALYZE TABLE 命令修复基数并将其备份到 20k-30k 并且查询再次快速运行。

我已开始监视所有表的基数,以查看该值如何随时间变化。我知道随着新数据的添加,基数会上升,我希望它会随着记录被删除而下降,但这个表很少会删除记录,但每次我查看它时,值都会上下波动。

MySQL 5.5.8 InnoDB

CentOS 5.7

关于我应该寻找什么的任何想法? COUT(*) = 402259

【问题讨论】:

bugs.mysql.com/bug.php?id=44760 ? 错误 44760 看起来非常相似,如果不是因为我使用的是 InnoDB 而不是 ndbcluster 并且该错误是在 5.1 版中报告的,并且希望我使用的 5.5 不会是一个如此古老的错误.还是很有趣的。 你找到原因了吗? 我没有找到导致基数下降的原因或解决它导致的问题的方法。我们知道,当我们的表具有高基数时,通常在优化表之后,我们的查询会非常快。活跃度高的桌子上的基数全天波动。如果基数下降超过 40%,则该表上的查询性能会下降,并且有时会锁定。任何需要超过 60 秒的查询都会被终止。我们也有 Icinga 监控下降的基数,以便在它发生之前让我们知道。尚无解决方案。 【参考方案1】:

InnoDB 表的统计数据是近似的,不准确。所以,如果你想知道一个字段的确切基数,你可以运行这个查询:

SELECT COUNT(DISTINCT field_name) FROM table_name

【讨论】:

所有从服务器的计数与主服务器 7657 相同。当我使用 SHOW INDEXES FROM table_name 时,主服务器上的基数计数为 9305,从服务器上的基数计数为 21189、11503、7742 和 6913。所有从站都落后于主站零秒。数字保持不变几分钟,然后从 21189 下降到 7742,而所有其他从属和主控保持不变。 这是可能的,也很正常。实际上,即使它们具有完全相同的数据,也很难在不同的服务器上获得相同的统计信息。这背后的因素很少。主要因素是 InnoDB 存储数据和索引的方式。它使用 B-Tree 作为索引,从中显示基数。试试看master和slave上文件的大小,会不一样的。

以上是关于是啥导致 MySQL 基数减少?的主要内容,如果未能解决你的问题,请参考以下文章

mysql选错娱乐平台源码搭建索引的原因与处理

校正系数i是啥意思

是啥导致本地 mysql 服务器查询速度出现随机峰值?

是啥导致了这个 Heroku mysql 连接错误? (尝试将前端连接到后端 POST 请求)

MYSQL 优化,持续更新收藏

mysql和access的区别是啥?