慢查询日志: 由数据库自身提供的功能,用于记录所有执行时间超过指定阈值(long_query_time)的SQL语句。

开启日志(以MySQL为例)
在数据库配置文件(如 my.cnf 或 my.ini)中设置:

my.ini

slow_query_log = 1
slow_query_log_file = /var/lib/mysql/slow.log
long_query_time = 1    # 单位:秒。建议从1秒开始,逐步调低至0.1s以捕获更多问题SQL
log_queries_not_using_indexes = 1 # 记录未使用索引的查询(需谨慎,可能产生大量日志)
log_output = FILE

业务高峰时段或重现性能问题期间,让系统运行一段时间(如15-30分钟),确保慢查询日志能充分捕获潜在的性能瓶颈语句

mysqldumpslow: MySQL自带工具,可对慢日志进行汇总统计

mysqldumpslow -s t -t 10 /var/lib/mysql/slow.log # 按总耗时排序,取出前10条


pt-query-digest (Percona Toolkit): 行业标准工具,功能强大。它能提供一份极其详细的报告,包括:
按总响应时间排序的SQL排名,迅速找到“最耗资源”的查询。
每条SQL的执行次数、平均/最大/最小执行时间、锁等待时间等。
同一类SQL的归一化(Fingerprint)统计,避免相同模式SQL的重复计算。

根据 pt-query-digest 的报告,优先选择执行次数最多和单次执行时间最长的SQL作为首要优化对象。

对于筛选出的每一条问题SQL,使用 EXPLAIN 或 EXPLAIN ANALYZE(提供实际执行数据)命令进行分析:

EXPLAIN SELECT * FROM orders WHERE user_id = 100 AND status = 'shipped';

type列(访问类型): 这是最重要的字段。性能从优到劣大致为:
system > const > eq_ref > ref > range > index > ALL

如果出现 ALL(全表扫描),几乎必定是性能杀手。如果出现 index(全索引扫描),也通常需要优化。
key列(实际使用的索引): 检查优化器是否使用了您预期的索引。如果为 NULL,则表示未使用索引。
rows列(预估扫描行数): 表示为了找到目标记录,优化器预估需要扫描的行数。这个值应该尽可能小。
Extra列(额外信息): 这里包含了极其重要的细节:
Using filesort: 表示MySQL无法利用索引完成排序,需要额外的排序步骤,CPU密集型操作。
Using temporary: 表示需要创建临时表来处理查询,常见于GROUP BY和ORDER BY组合操作,性能极差。
Using where: 表示在存储引擎检索行后,服务器层再次进行了过滤。如果 rows 值很大,说明索引筛选性不好。

mysql数据库查询优化:
发现 type: ALL 且 key: NULL → 建议: 为 WHERE 子句中的条件列创建索引。
发现 type: ref 但 rows 值依然很大 → 建议: 考虑当前索引的选择性不高,可能需要创建更高效的复合索引或优化查询条件。
发现 Extra: Using filesort → 建议: 检查ORDER BY子句的字段,尝试通过创建包含该列的索引来避免排序。
发现 Extra: Using temporary → 建议: 优化查询结构,检查GROUP BY和ORDER BY的列,或考虑简化查询。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐