大表的mysql性能问题

Posted

技术标签:

【中文标题】大表的mysql性能问题【英文标题】:mysql performance issue for large table 【发布时间】:2019-03-16 08:32:49 【问题描述】:

您有一个非常大的表——超过 5 亿条记录。该表已完全标准化。该表是一个 innodb 表。查询速度比可接受的要慢,即使它们已尽可能优化。尽管该表已经很慢,但预计在接下来的 6 个月内它的规模将翻一番。您会考虑采取哪些措施来解决当前的性能问题并让表中的数据可能翻两番?

我了解到,如果查询速度很慢,则问题出在处理能力、RAM、磁盘或服务器数量上。您能否用儿童语言讲述云计算或负载平衡或添加 RAM/CPU 功率/磁盘如何帮助将如此大量行的查询响应时间从 7 秒增加到 1 秒?假设您有 X 服务器和 Y RAM 以及 C 容量的 Z 光盘,这给了我 S1 秒的查询响应时间。如何改变 X、Y、Z、C 以将 S1 增加/减少 1 秒?

【问题讨论】:

答案真的取决于表结构和用例。 如果有任何日志表或任何其他表,您每天都期待大量数据,那么最好将这些数据迁移到 MongoDB 或任何其他 NoSQL db @apokryfos 表结构和用例被冻结。 Channaveer Hakari db 固定为 mysql。系统已经上线,我们无法承受重大变化。 没有任何更具体的信息,我不知道我们是否可以说这不是纯粹的猜测。 将“尽可能优化”视为理所当然(99% 的 *** 案例并非如此),其中 99% 的案例将受益于更快的 i /o,其中 ram>ssd>hdd(仅受您想花多少钱的约束)。要在几秒钟内得到一个数字:启动profiling,运行您的查询并总结。这是您通过购买足够的内存来保存所有数据可以节省的时间的近似值。如果更少的 ram 就足够了,将再次取决于您的具体情况。 【参考方案1】:

“表格完全标准化”——既然有“过度标准化”这样的东西,让我们看看表格的SHOW CREATE TABLE

Fact 表(具有 500M 行的那个)上的大量索引会损害INSERT 的性能。 连续值(日期、日期时间、数字)不应进行规范化。当您需要搜索一系列此类值时,规范化会造成很大的影响

“我了解到,如果查询速度很慢,则问题出在处理能力、RAM、磁盘或服务器数量上。” ——那是老妇人的故事。通常有一些方法可以改进查询和/或架构的索引和/或公式化(如上所述)。

您熟悉“复合”索引吗?

“您能否用儿童语言讲述云计算或负载平衡或添加 RAM/CPU 功率/磁盘如何帮助将如此大量行的查询响应时间从 7 秒增加到 1 秒?”答案:“这些都无济于事。” MySQL 1 个 CPU 执行一次查询,服务器上的 I/O 也很可能是单线程的。 MySQL 中不存在并行性(您提到的);当它这样做时,由用户来编写代码,然后哀叹它没有像预期的那样有帮助。

“那么最好将这些数据迁移到 MongoDB 或任何其他 NoSQL 数据库”——你没有抓住重点。如果需要读取 500M 行(甚至 1M),则需要时间。没有灵丹妙药可以让 I/O 更快。

抱歉含糊其辞,但有许多原则可以显着加快处理 500M 行的速度。

数据仓库的一大帮助是“汇总表”。他们经常让事情变得快10 倍。但它们需要来构建和维护它们。 (同样,由于缺乏关于您的用例的细节,我很模糊。)

“对于 99% 的 *** 案例,情况并非如此”——也许只有 98%。

唯一能让您加速 2 倍的硬件修复是用 SSD 替换旋转驱动器。 CPU 在 18 年中没有太大改进。当您有 64 个连接时,64 核会有所帮助,但在您对 1 个连接的延迟进行计时时则无济于事。当需要的数据可以跨多个服务器分离时,最好进行分片。

【讨论】:

【参考方案2】:

我建议启用slow query log 并从记录需要超过 5 秒的查询开始。 应该对来自日志的查询进行性能分析。 在此之后又一轮 4,3,2,1 秒。 完成此分析后不要忘记切换日志。

如果您仍然很慢,那么您可以考虑一下您的硬件 - 它是慢速 san、普通硬盘还是 sd?在此之后,您可以考虑您的内存...您是否需要更多,因为系统一直在交换?最后但并非最不重要的一点是考虑你的 CPU ......但也许你在树莓派上 - 这通常很慢;-)

【讨论】:

感谢您的好评。我正在寻找关系或公式,我可以用它来决定 RAM/磁盘/CPU 的数量/大小,以在响应时间上有特别的差异,比如 n 大行数。你知道怎么解决吗?谢谢。 这取决于很多事情——优化并不总是一门精确的科学——更多的是大量的经验。此外,您还需要知道哪些螺栓无法转动不会改善问题。例如,添加索引会提高阅读速度,但写入索引会减慢速度。因此,您需要始终找到正确的平衡点。 你能举几个例子让我理解这个平衡!谢谢。 你最好读一本书,比如 o'reilly 的“高性能 MySQL:优化、备份和复制”。 @NN 请考虑首先考虑发布 SHOW GLOBAL VARIABLES LIKE 'read_%size' 的结果,然后再考虑发布 SHOW GLOBAL VARIABLES LIKE 'innodb_io_%' 的结果。上面提到的这本书可以在 ebay 上以不到 5 美元的价格买到,经过深入研究后,对你来说价值 500 美元。

以上是关于大表的mysql性能问题的主要内容,如果未能解决你的问题,请参考以下文章

将 MySQL 索引添加到大表的性能影响

MySQL大表性能优化

MySQL 性能:在大表中排序很慢,即使过滤的子集很小

使用带有大表的循环的 python 性能问题

多对多关系 - 大表的查询性能

SQL性能问题.现在表设计可以把一个大表按类型(各类型字段不相同)拆分成多个小表.拆分后比较方便.