7

我在一个使用 MySQL 5.0 数据库和 InnoDB 表的大型 Web 应用程序上工作。在过去的几个月里,我们两次经历了以下情况:

  1. 数据库服务器运行良好数周,负载低且查询速度慢。
  2. 以前快速运行的频繁执行的查询将突然开始运行非常缓慢。
  3. 数据库负载峰值和站点挂起。

这两种情况的解决方案都是在慢查询日志中找到慢查询,并在表上创建一个新的索引来加速它。应用索引后,数据库性能恢复正常。

最令人沮丧的是,在这两种情况下,我们都没有对即将到来的厄运发出警告。我们所有的监控系统(例如,系统负载、CPU 使用率、查询执行率、慢查询)都告诉我们数据库服务器运行良好。

问题 1:我们如何预测或完全避免这些临界点?

我们没有定期做的一件事是运行 OPTIMIZE TABLE 或 ANALYZE TABLE。我们很难找到关于手动执行这些操作的频率(如果有的话)的良好经验法则。(由于这些命令 LOCK 表,我们不想不加选择地运行它们。)这些场景听起来像是未优化表的结果吗?

问题 #2:我们应该手动运行 OPTIMIZE 还是 ANALYZE?如果有,多久一次?

有关该应用程序的更多详细信息:数据库使用模式约为 95% 读取,5% 写入;数据库每秒执行大约 300 个查询;在这两种情况下,慢查询中使用的表是相同的,并且有数十万条记录。

4

4 回答 4

7

MySQL 性能博客是一个很棒的资源。也就是说,这篇文章涵盖了正确调整 InnoDB 特定参数的基础知识。

我还发现MySQL 参考手册的 PDF 版本是必不可少的。第 7 章介绍了一般优化第 7.5 节介绍了您可以玩弄的特定于服务器的优化。

从您的服务器的声音来看,查询缓存对您来说可能具有巨大的价值。

参考手册还为您提供了一些关于慢查询、缓存、查询优化甚至使用索引进行磁盘查找分析的详细信息。

可能值得您花时间研究多主复制,允许您完全锁定一台服务器并运行 OPTIMIZE/ANALYZE,而不会影响性能(因为 95% 的查询是读取,另一台服务器可以只管理写入美好的)。

第 12.5.2.5 节详细介绍了 OPTIMIZE TABLE,第 12.5.2.1 节详细介绍了 ANALYZE TABLE。

更新您的编辑/重点:

问题#2很容易回答。从参考手册:

优化:

如果您删除了表的大部分内容,或者您​​对具有可变长度行的表进行了许多更改,则应使用 OPTIMIZE TABLE。[...] 您可以使用 OPTIMIZE TABLE 回收未使用的空间并对数据表进行碎片整理。

并分析:

ANALYZE TABLE 分析并存储表的键分布。[...] MySQL 使用存储的键分布来决定当您对常量以外的其他内容执行连接时应该连接表的顺序。此外,在决定将哪些索引用于查询中的特定表时,可以使用键分布。

OPTIMIZE 很适合在您有空闲时间时运行。MySQL 对已删除的行进行了很好的优化,但是如果您从表中删除 20GB 的数据,那么运行它可能是个好主意。在大多数情况下,绝对不需要良好的性能。

ANALYZE 更为关键。如前所述,当涉及到几乎任何查询时,让 MySQL 所需的表数据(由 ANALYZE 提供)非常重要。它应该在共同的基础上运行。

问题 #1更像是一个技巧。发生这种情况时,我会非常仔细地观察服务器,即磁盘 I/O。我敢打赌,您的服务器正在破坏您的交换或(InnoDB)缓存。在任何一种情况下,它都可能与查询、调整或负载相关。未优化的表可能会导致此问题。如前所述,运行 ANALYZE 可以极大地提高性能,并且可能也会有所帮助。

于 2009-02-17T21:09:57.780 回答
1

我还没有找到任何预测 MySQL“临界点”的好方法——而且我遇到了一些。

话虽如此,我发现引爆点与桌子大小有关。但不仅仅是原始表大小,而是查询的“感兴趣区域”有多大。例如,在一个超过 300 万行和大约 40 列(大约四分之三的整数)的表中,大多数可以根据索引轻松选择其中一部分的查询速度很快。但是,当一个索引列的查询中的一个值意味着三分之二的行现在“有趣”时,查询现在比正常情况慢约 5 倍。教训:尝试整理您的数据,这样就不需要进行此类扫描。

但是,这种行为现在为您提供了一个可供查找的大小。这个大小将在很大程度上取决于您的服务器设置、MySQL 服务器变量以及表的模式和数据。

同样,如果周期为两周,我看到报告查询在合理的时间(约 45 秒)内运行,但如果周期延长至四周,则需要半小时。

于 2009-02-18T01:51:38.180 回答
0

使用慢查询日志,这将帮助您缩小要优化的查询范围。

对于时间紧迫的查询,有时最好通过使用提示来保持稳定的计划。

于 2009-02-17T21:01:30.733 回答
0

听起来您遇到了令人沮丧的情况,并且可能不是最好的代码审查流程和开发环境。

每当您向代码中添加新查询时,您都需要检查它是否已准备好适当的索引并将其添加到代码版本中。

如果您不这样做,您的第二个选择是不断监控慢查询日志,然后击败开发人员;我的意思是去添加索引。

有一个选项可以启用对不使用索引的查询的日志记录,这对您很有用。

如果有一些查询“工作并停止工作”(但正在“使用和索引”),那么查询可能一开始就不是很好(索引中的基数低;连接效率低;...)并且在添加查询时仔细评估查询的第一条规则将适用。

对于问题 #2 - 在 InnoDB 上,“分析表”基本上可以免费运行,所以如果你的连接性能不好,运行它并没有什么坏处。除非表中键的平衡发生很大变化,否则它不太可能有帮助。它几乎总是归结为错误的查询。“优化表”重建 InnoDB 表;以我的经验,它的帮助足以值得让表在持续时间内不可用(或在它运行时进行主-主故障转移)的麻烦,这是相对罕见的。

于 2009-02-18T00:00:19.273 回答