min_examined_row_limit 对慢查询日志的影响
2025-01-20 20:49 abce 阅读(25) 评论(0) 编辑 收藏 举报执行了以下一个很慢的 SQL,但是在慢查询日志中却没有发现对应的 SQL 语句。
1 2 3 4 5 6 7 | > select count (*) from myabc_abcde_expo_vv; + -----------+ | count (*) | + -----------+ | 509600169 | + -----------+ 1 row in set (3 min 3.76 sec) |
第一反应是不是库没有开启慢查询日志的功能?于是检查一下关于慢查询的相关设置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | > show variables like '%query%' ; + ------------------------------+----------+ | Variable_name | Value | + ------------------------------+----------+ | binlog_rows_query_log_events | ON | | ft_query_expansion_limit | 20 | | have_query_cache | NO | | long_query_time | 2.000000 | | query_alloc_block_size | 8192 | | query_prealloc_size | 8192 | | slow_query_log | ON | | slow_query_log_file | slow.log | + ------------------------------+----------+ 8 rows in set (0.00 sec) > show variables like '%slow%' ; + -----------------------------+----------+ | Variable_name | Value | + -----------------------------+----------+ | log_slow_admin_statements | ON | | log_slow_extra | ON | | log_slow_replica_statements | OFF | | log_slow_slave_statements | OFF | | slow_launch_time | 2 | | slow_query_log | ON | | slow_query_log_file | slow.log | + -----------------------------+----------+ 7 rows in set (0.00 sec) > show variables like '%log_queries_not_using_indexes%' ; + -------------------------------+-------+ | Variable_name | Value | + -------------------------------+-------+ | log_queries_not_using_indexes | ON | + -------------------------------+-------+ 1 row in set (0.00 sec) > show variables like '%log_slow%' ; + -----------------------------+-------+ | Variable_name | Value | + -----------------------------+-------+ | log_slow_admin_statements | ON | | log_slow_extra | ON | | log_slow_replica_statements | OFF | | log_slow_slave_statements | OFF | + -----------------------------+-------+ 4 rows in set (0.01 sec) > show variables like '%min_examined_row_limit%' ; + ------------------------+-------+ | Variable_name | Value | + ------------------------+-------+ | min_examined_row_limit | 100 | + ------------------------+-------+ 1 row in set (0.01 sec) |
可以看到,慢查询相关的参数都做了配置。
根据官方文档的介绍,InnoDB 通过遍历最小的可用二级索引来处理 SELECT COUNT(*) 语句,除非索引或优化器 hint 指示优化器使用其它的索引。如果没有二级索引,InnoDB 会通过扫描聚簇索引来处理 SELECT COUNT(*) 语句。
而这张表上既有自增主键,也创建了二级索引。这里通过查看执行计划,也可以看到选择了二级索引:
1 2 3 4 5 6 | > desc select count (*) from myabc_abcde_expo_vv; + ----+-------------+---------------------+------------+-------+---------------+-----------------+---------+------+-----------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | + ----+-------------+---------------------+------------+-------+---------------+-----------------+---------+------+-----------+----------+-------------+ | 1 | SIMPLE | myabc_abcde_expo_vv | NULL | index | NULL | idx_symbol_data | 4 | NULL | 505767703 | 100.00 | Using index | + ----+-------------+---------------------+------------+-------+---------------+-----------------+---------+------+-----------+----------+-------------+ |
此外 log_queries_not_using_indexes 的值为 on,按道理无论这个 SQL 有没有使用到索引,也应该被记录到日志中。
其它相关参数主要是设置为是否开启,所以,这里将重点转移到了参数 min_examined_row_limit。如文档所说,查询检查的记录数少于 min_examined_row_limit 设定的行数时不会记录到慢查询日志中。
上面这个 SQL 检索的表包含了509600169条记录,这里的 min_examined_row_limit 的值为100,主观感觉上该参数不会导致该 SQL 不写入慢查询日志。
但还是做了一下尝试,将 min_examined_row_limit 的值替换成了默认值,即 0。然后执行上面的慢查询,发现慢日志中已经有了对应的SQL语句:
1 2 3 4 5 6 7 8 | # Time : 2025-01-19T17:28:20.501023+08:00 # User @Host: root[root] @ localhost [] Id: 8 # Query_time: 176.989435 Lock_time: 0.000018 Rows_sent: 1 Rows_examined: 0 Thread_id: 8 Errno: 0 Killed: 0 Bytes_received: 47 Bytes_sent: 64 Read_first: 0 Read_last: 0 Read_key: 30 Re ad_next: 34 Read_prev: 0 Read_rnd: 0 Read_rnd_next: 0 Sort_merge_passes: 0 Sort_range_count: 0 Sort_rows: 0 Sort_scan_count: 0 Created_tmp_disk_tables: 0 Created_tmp_tables: 0 Start: 20 25-01-19T17:25:23.511588+08:00 End : 2025-01-19T17:28:20.501023+08:00 use pms; SET timestamp =1737278723; select count (*) from myabc_abcde_expo_vv; |
不过,这里可以清楚的看到:
1 | Rows_examined: 0 |
这里的 Rows_examined 的实际含义是:
1 | The number of rows examined by the server layer ( not counting any processing internal to storage engines). |
因为慢SQL在引擎层通过二级索引完成对表记录数的统计,并将结果直接返给server层,server层检查的行数就是0,在 min_examined_row_limit = 100 的时候,就不会将该SQL记录到慢日志中。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~
2023-01-20 数据库损坏指南(1)--概述
2022-01-20 shell脚本计算时间差
2022-01-20 Dataguard环境添加tempfile
2016-01-20 SQL plan directives