发布于2026-05-22 阅读(0)
扫一扫,手机访问

直接开启 log_queries_not_using_indexes = ON,恐怕是新手DBA最常踩的坑。这个操作看似一劳永逸,实则风险极高——它会让每一条没走索引的SQL,哪怕只扫描一行、耗时零点几毫秒,都被完整记录。结果就是,慢查询日志可能在几小时内迅速膨胀,直接填满磁盘空间。因此,在生产环境中,这个参数必须与 min_examined_row_limit 搭配使用,设置一个合理的扫描行数门槛。
那么,临时排查问题时,如何配置才算稳妥呢?可以参考以下组合拳:
SET GLOBAL slow_query_log = 'ON'SET GLOBAL long_query_time = 1(对于核心业务,甚至可以设为 0.5 以捕捉更细微的慢查询)SET GLOBAL min_examined_row_limit = 1000(只记录那些扫描行数超过1000的语句,有效过滤噪音)SET GLOBAL log_queries_not_using_indexes = 'OFF'(关键一步:先别开它!)如果需要永久生效,记得将配置写入 /etc/my.cnf 文件的 [mysqld] 配置段,然后重启服务。这里有个细节需要注意:修改后务必执行 SHOW VARIABLES LIKE '%slow%' 来确认新值已成功加载。尤其是MySQL 8.0及以上版本,变量命名风格可能使用下划线,例如 slow_query_log,而不是旧版的 slow-query-log。
慢查询日志里的 Query_time 和 Rows_examined 只能告诉你“查询慢了”,却无法揭示“为什么慢”。真正的侦探工具是 EXPLAIN 命令。面对它的输出结果,不必被所有字段吓倒,集中火力盯紧以下三列,就能抓住问题的关键:
type:这是访问类型。如果看到 ALL,基本就等于宣告了全表扫描,索引大概率没起作用。理想的状态应该是 range(范围扫描)或 ref(等值查询)。key:这里显示实际使用的索引名称。如果这一列是 NULL
rows:这是优化器预估需要扫描的行数。如果这个数字远大于查询实际返回的行数(比如一个 SELECT COUNT(*) 只返回1行,但 rows 却显示500000),那就要高度警惕了。这通常指向索引失效,或者表的统计信息已经过时,误导了优化器。进阶一点,使用 EXPLAIN FORMAT=JSON 还能看到一个叫 filtered 的字段。它表示经过条件过滤后,剩余行数的预估百分比。如果这个值低于10%,就是一个明确的警告信号——说明当前索引的区分度太低,或者WHERE条件的选择性太差,需要重新审视索引设计。
给表加联合索引,可不是把字段随便堆在一起就完事了。建错了顺序,索引就等于白建,查询时依然会慢如蜗牛。
举个例子,假设有一个常见查询:WHERE status = 'paid' AND create_time > '2023-01-01' ORDER BY amount DESC。索引该怎么建?
INDEX(create_time, status)。因为 create_time 是范围查询(>),根据最左前缀原则,它后面的 status 字段将无法被用于索引过滤,实际上就失效了。INDEX(status, create_time)。将等值查询的字段 status 放在前面,先精准定位到‘paid’状态的行,然后再对 create_time 进行范围扫描,这完全符合索引的最左前缀匹配规则。id, status, amount 这几个字段,那么可以考虑 INDEX(status, create_time, amount)。这就是“覆盖索引”的妙用——所有需要的数据都在索引树里,无需回表查询数据行,性能提升立竿见影。最后,有两个原则务必牢记:一是避免为使用 LIKE '%xxx' 这种前导通配符的字段单独建立索引,它用不上;二是不要在WHERE条件中对索引字段使用函数,比如 WHERE DATE(create_time) = '2023-01-01',这会让索引瞬间失效,强制进行全表扫描。
很多数据库管理员一上来就热衷于调整 innodb_buffer_pool_size 或调低 long_query_time,却忽略了一些本身就会干扰诊断过程的参数设置。
log_output = TABLE:这个设置看起来很方便,慢查询直接记录在 mysql.slow_log 系统表里,随手就能查。但在高并发场景下,向这个表写入日志本身会产生锁和I/O开销,可能反过来拖慢正常的业务查询。相比之下,使用文件模式(log_output = FILE)通常更为轻量和安全。long_query_time = 0:在测试环境用于捕捉所有查询无可厚非。但如果上线后忘记调整回来,海量的日志会瞬间淹没磁盘,甚至连 mysqldumpslow 这样的日志分析工具都可能因为解析过大的文件而卡住。slow_query_log_file 路径:如果把慢查询日志文件放在系统盘,或者与数据库的数据目录(datadir)放在同一块物理磁盘上,就会产生激烈的I/O竞争。这可能导致慢查询记录出现延迟,甚至在极端情况下丢失最后几条关键的日志信息。还有一个容易被忽略的参数是 log_slow_admin_statements。它默认是关闭的,因此像 ALTER TABLE、ANALYZE TABLE 这类管理语句即使执行很慢,也不会出现在常规的慢查询日志中。然而,这类语句虽然执行频率不高,可一旦变慢,影响的是整个表的可用性。如果你在日志里始终找不到这类“元凶”,记得检查并打开这个开关。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
4
5
6
7
8
9