是啥导致 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 基数减少?的主要内容,如果未能解决你的问题,请参考以下文章