如何对慢速查询进行故障排除并提高其在 Amazon RDS for MySQL 中的性能?
我想对慢速查询进行故障排除并提高其在 Amazon Relational Database Service (Amazon RDS) for MySQL 中的性能。
解决方法
监控您的资源和数据库性能
使用 Amazon CloudWatch 确定您的查询何时会提高资源利用率。
监控以下 CloudWatch 指标:
- DatabaseConnections
- NetworkReceiveThroughput
- WriteThroughput 和 ReadThroughput
- WriteLatency 和 ReadLatency
- WriteIOPS 和 ReadIOPS
- FreeStorageSpace
- BurstBalance
使用 Amazon RDS 控制台来确定查询何时会降低数据库性能。此外,检查您的 RDS 数据库实例状态,以确定可能影响数据库性能的活动或计划进程。检查数据库性能不佳时发生的 Amazon RDS 事件。
使用增强监控来查看工作负载中的操作系统 (OS) 列表和系统指标。默认情况下,增强监控的时间间隔为 60 秒。最佳做法是为更详细的数据点设置 1–5 秒的时间间隔。
检查增加资源利用率的工作负载
确定查询提高资源利用率或降低性能的时间后,打开性能详情以确定必须优化的查询。
重要事项:性能详情将于 2025 年 11 月 30 日到期。您可以在 2025 年 11 月 30 日之前升级到数据库洞察的高级模式。如果您不升级,则使用性能详情的数据库集群将默认为数据库洞察的标准模式。只有数据库洞察的高级模式才支持执行计划和按需分析。如果您的集群默认为标准模式,则您可能无法在控制台上使用这些功能。要开启高级模式,请参阅开启适用于 Amazon RDS 的数据库洞察的高级模式和开启适用于 Amazon Aurora 的数据库洞察的高级模式。
要检查您的工作负载,请完成以下步骤:
- 访问性能详情控制面板上的数据库负载图表。
- 检查按等待加载 (AAS) 列以确定在资源利用率提高或查询性能下降时使用等待事件最多的工作负载。
**注意:**负载图表上较大的色带表示对您的工作负载影响最大的等待类型。如果您的工作负载持续超过最大 vCPU,请修改您的实例类。 - 在 Top SQL 选项卡上,搜索构成工作负载的各个查询。
要识别运行缓慢的查询,您还可以在参数组中打开 slow_query_log 并将日志发布到 CloudWatch Logs。
提升查询性能
使用 EXPLAIN 语句
检查查询操作计划以确定您的查询是否使用了相应的索引。使用 EXPLAIN 优化您的查询并查看有关 MySQL 如何运行查询的详细信息。有关详细信息,请参阅 MySQL 网站上的 Optimizing Queries with EXPLAIN(使用 EXPLAIN 优化查询)。
为避免全表扫描,请运行 EXPLAIN 语句来确定您的查询是否使用索引。在 EXPLAIN 输出中,检查表名称、使用的密钥以及为查询扫描的行数。有关详细信息,请参阅 MySQL 网站上的 EXPLAIN statement(EXPLAIN 语句)。
如果输出未显示正在使用的密钥,则在 WHERE 子句中的列上创建索引。如果该表具有所需的索引,请检查表统计数据是否为最新。当统计数据为最新时,查询优化器会使用具有正确基数的最具选择性的索引,从而使查询性能得到提升。有关详细信息,请参阅 MySQL 网站上的 The INFORMATION_SCHEMA STATISTICS Table(INFORMATION_SCHEMA STATISTICS 表)。
使用 ANALYZE TABLE
使用 ANALYZE TABLE 更新您的查询统计数据。有关详细信息,请参阅 MySQL 网站上的 ANALYZE TABLE statement(ANALYZE TABLE 语句)。
使用 EXPLAIN ANALYZE
对于 MySQL 8.0,使用 EXPLAIN ANALYZE。EXPLAIN ANALYZE 语句显示了 MySQL 在何处为您的查询分配时间以及分配该时间的原因。查询完成后,EXPLAIN ANALYZE 会打印计划及其测量结果。有关详细信息,请参阅 MySQL 网站上的 Obtaining Information with EXPLAIN ANALYZE(使用 EXPLAIN ANALYZE 获取信息)。
检查历史列表长度
InnoDB 使用多版本并发控制 (MVCC)。MVCC 维护同一记录的多个副本以保持读取一致性。历史列表长度是包含历史列表中修改的撤消日志的总数。当有一个写入或读取数据的长时间运行的事务时,历史列表的长度会增加,直到事务完成或回滚为止。此外,当其他事务修改长时间运行的事务使用的表时,历史列表长度也会增加。
最佳做法是避免在数据库上进行打开或长时间运行的事务。而应小批量提交数据。然而,如果您的工作负载需要多个打开或长时间运行的事务,则数据库的历史列表长度会很长。
如果您不监控历史列表长度,则性能可能会随着时间的推移而下降。历史列表长度过高还可能导致资源利用率高、SELECT 语句性能缓慢且不一致以及存储空间增加。
**注意:**长时间运行的事务并不是历史列表长度激增的唯一原因。如果清除线程无法匹配数据库的变化,则历史列表长度仍然很高。在极端情况下,您还可能会遇到数据库中断的情况。
要检查您的历史列表长度,请运行以下命令:
SHOW ENGINE INNODB STATUS;
**注意:**SHOW ENGINE INNODB STATUS 语句可获取有关事务处理、等待事件和死锁的信息。有关详细信息,请参阅 MySQL 网站上的 SHOW ENGINE statement(SHOW ENGINE 语句)。
输出示例:
\------------ TRANSACTIONS ------------Trx id counter 26368570695 Purge done for trx's n:o < 26168770192 undo n:o < 0 state: running but idle History list length 1839
要使用性能详情检查历史列表长度,请完成以下步骤:
- 打开 Amazon RDS 控制台。
- 在导航窗格中,选择 Performance Insights(性能详情),然后选择要查看其指标的数据库。
- 选择 Metrics tab(“指标”选项卡),
- 在 Metrics dashboard(指标控制面板)菜单上,选择 Custom dashboard(自定义控制面板)。
- 选择 Add widget(添加小组件),然后搜索并选择 Trx Rseg History Len 指标。
- 选择 Add Widget(添加小组件)。
如果 DML 写入导致历史记录列表长度增加,请数据库管理员结束写入语句。
**注意:**回滚中断事务的更新需要很长时间。
解决被阻止的查询
在 MySQL 8.0 中,您可以在 data_lock_waits 表的性能架构中找到锁定等待。有关详细信息,请参阅 MySQL 网站上的 Using InnoDB Transaction and Locking Information(使用 InnoDB 事务和锁定信息)。
示例:
SELECT r.trx\_id waiting\_trx\_id, r.trx\_mysql\_thread\_id waiting\_thread, r.trx\_query waiting\_query, b.trx\_id blocking\_trx\_id, b.trx\_mysql\_thread\_id blocking\_thread, b.trx\_query blocking\_query FROM performance\_schema.data\_lock\_waits w INNER JOIN information\_schema.innodb\_trx b ON b.trx\_id = w.blocking\_engine\_transaction\_id INNER JOIN information\_schema.innodb\_trx r ON r.trx\_id = w.requesting\_engine\_transaction\_id;
有关详细信息,请参阅为什么在没有其他活动会话的情况下,对 Amazon RDS for MySQL 数据库实例的查询会被阻止?
使用 SHOW PROFILE 语句
对速度较慢的查询进行分析,以了解会话花费最多时间的状态。有关详细信息,请参阅 MySQL 网站上的 SHOW PROFILE statement(SHOW PROFILE 语句)。
使用 SHOW FULL PROCESSLIST 语句
运行 SHOW FULL PROCESSLIST 语句并使用增强监控来查看您当前在数据库服务器上执行的操作列表。有关详细信息,请参阅 MySQL 网站上的 SHOW PROCESSLIST statement(SHOW PROCESSLIST 语句)。

