告别慢查询熬夜排查:三步用 SQLAdvisor 生成 MySQL 索引优化建议

📅 2026/8/15 15:51:37
告别慢查询熬夜排查:三步用 SQLAdvisor 生成 MySQL 索引优化建议
告别慢查询熬夜排查三步用 SQLAdvisor 生成 MySQL 索引优化建议【免费下载链接】SQLAdvisor输入SQL输出索引优化建议项目地址: https://gitcode.com/gh_mirrors/sq/SQLAdvisor深夜两点你的手机突然被监控告警震醒——某个核心接口响应从 30ms 飙到 3 秒线上告警群里一片1。你登录数据库一看一条 SELECT 查询把整张表扫了个遍慢查询日志里它排名第一。加个索引就能解决但字段这么多到底该给谁加加在前面还是后面如果你也经历过这种人工试索引的折磨那么本文介绍的 SQLAdvisor 就是为你准备的答案。它由美团点评 DBA 团队开源核心功能一句话说清输入 SQL自动输出索引优化建议。为什么是 SQLAdvisor三个让它会说话的硬实力在它出现之前大家是怎么加索引的要么靠 DBA 多年的经验直觉要么一条条 EXPLAIN 手动验证要么干脆把字段全塞进索引里碰运气。SQLAdvisor 则把索引怎么建变成了一条可复现的流水线它的底气来自下面三点。1. 基于 MySQL 原生词法解析而不是正则碰运气很多工具解析 SQL 靠正则表达式遇到复杂写法就翻车。SQLAdvisor 直接复用 MySQL 自身的解析器sqlparser 模块把 SQL 拆成一棵标准的语法树从根上保证读得懂你的语句这是它输出可靠建议的地基。2. 计算字段区分度让高价值字段排前面索引不是字段越多越好排列顺序更重要。SQLAdvisor 会估算每个字段的区分度Cardinality区分度越高的字段越适合放在索引前列。它甚至会对字段选择度低于 30的低价值条件直接放弃避免给你一堆没用的建议。3. 处理多表 Join 与驱动表选择逼近真实执行计划多表关联是索引优化里最头疼的场景。SQLAdvisor 会解析 Join 关系、构建表关系树并通过 EXPLAIN 估算各表结果集大小选结果集最小的表作为驱动表再给被驱动表补齐 Join 条件索引——这一整套逻辑和 MySQL 优化器的工作方式高度一致。下面这张图就是 SQLAdvisor 从收到 SQL 到输出索引建议建议的完整处理流程零基础上手SQLAdvisor 安装教程三分钟版别被编译源码四个字吓到整个过程其实只有三步跟着走就行。第一步准备环境需要 GCC 4.8、CMake 2.8、glib2 开发库以及 MySQL/Percona 客户端库编译依赖perconaserverclient_r。CentOS 系一行搞定yum install cmake libaio-devel libffi-devel glib2 glib2-devel再装上Percona-Server-shared-56因为编译 sqladvisor 时依赖它的客户端库。如果装完后链接报错多半是缺少软链接补一条即可cd /usr/lib64/ ln -s libperconaserverclient_r.so.18 libperconaserverclient_r.so第二步克隆源码并编译 sqlparser先拿到项目源码git clone https://gitcode.com/gh_mirrors/sq/SQLAdvisor然后编译 SQL 解析模块。为什么先编它因为 sqladvisor 本体是依赖这个解析库的顺序反了会找不到头文件cmake -DBUILD_CONFIGmysql_release -DCMAKE_BUILD_TYPEdebug -DCMAKE_INSTALL_PREFIX/usr/local/sqlparser ./ make make install这里的CMAKE_INSTALL_PREFIX就是解析库的安装目录建议保持默认值别乱改后面的编译会依赖它。第三步编译 sqladvisor 本体cd SQLAdvisor/sqladvisor/ cmake -DCMAKE_BUILD_TYPEdebug ./ make执行完当前目录下会生成一个sqladvisor可执行文件这就是我们要的主角。更多安装细节见官方文档 doc/QUICK_START.md。第一次运行验证你的第一条索引建议连接数据库的姿势很简单参数名与值之间用空格隔开./sqladvisor -h 127.0.0.1 -P 3306 -u root -p 密码 -d testdb -q SELECT * FROM orders WHERE user_id100 AND create_time2023-01-01 -v 1其中-h/-P/-u/-p/-d分别对应主机、端口、账号、密码、数据库名-q是待分析的 SQL-v 1表示输出日志。如果一切正常它会直接告诉你orders表建议添加(user_id, create_time)这样的索引建议。一个贯穿全篇的小案例区分度和最左前缀到底怎么算我们用上面的订单表查询来拆解。表里有几百万行订单user_id一个用户可能只下单几十次而create_time每天都有成千上万条记录——直觉上user_id比create_time更容易把数据筛到很小这在 SQLAdvisor 里就叫区分度高。SQLAdvisor 拿到 SQL 后会先通过show table status拿到表总行数再挑一个表上现有的最优索引做采样估算每个条件字段的区分度然后按区分度从高到低排列字段同时套用 MySQL 索引的最左前缀原则等值条件的字段放最前面。于是user_id100排在create_time2023-01-01前面最终建议(user_id, create_time)。这个算区分度 → 排序 → 组合索引的过程可以参考下面这张流程图理解起来更直观顺便说一句内部对索引列的整体排序优先级是等值条件 (group by | order by) 非等值条件。如果 SQL 里带了排序或分组它会额外判断这些字段是否来自同一张表、排序方向是否一致再决定要不要把它们并入索引——多表场景下的 Join 关系解析逻辑见下图⚠️ 避坑清单新手最容易踩的 6 个坑工具虽好但如果你不摸清它的脾气很容易得到看似有用、实则无效的结果。以下是最常见的坑OR 条件、子查询、函数条件会被直接忽略。SQLAdvisor 只处理 AND 连接的普通条件遇到 OR、子查询、WHERE DATE(create_time)...这类带函数的写法会跳过。这不是 bug是设计取舍遇到这类 SQL 只能人工介入。like 非前缀匹配会被丢弃。LIKE abc%能用上索引但LIKE %abc会被丢弃别指望它给出离谱建议。命令行传 SQL 要转义双引号和反引号。比如-q SELECT * FROM t WHERE name\x\反引号建议直接去掉。嫌麻烦的话官方推荐用配置文件方式调用把参数写进sql.cnf然后./sqladvisor -f sql.cnf -v 1。group by 和 order by 有限制字段必须来自同一张表且是驱动表两者只能保留一个order by 的排序方向必须完全一致否则整列丢弃。不要用它分析不支持的语句就放弃。它支持 insert、update、delete、select、insert select、select join 等常见 SQL覆盖日常绝大多数场景。建议不等于事实。工具给出的是优化建议上线前请务必用 EXPLAIN 手动验证一遍执行计划尤其是大数据量、高并发的核心表。小结谁适合用 SQLAdvisor如果你是新系统上线前的 SQL 性能评估者是每天翻慢查询日志的业务 DBA或者是刚接手线上库、对索引还拿不准的开发者SQLAdvisor 都能帮你把凭经验猜索引变成按数据说话。它的定位不是取代你而是帮你把索引优化的脏活累活标准化、工具化——三分钟装好一条命令出建议剩下的判断交给你的业务直觉。想深入理解它的解析树分解、区分度算法细节可以接着读项目自带的 doc/THEORY_PRACTICES.md 和 doc/FAQ.md。【免费下载链接】SQLAdvisor输入SQL输出索引优化建议项目地址: https://gitcode.com/gh_mirrors/sq/SQLAdvisor创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考