【优化】Mysql指定索引查询或忽略某个索引
1. 基本语法
主要是在 FROM
子句的表名后面添加索引提示。
SELECT * FROM table_name[USE | FORCE | IGNORE] INDEX (index_name)WHERE ...;
2. 三种提示的区别
提示 | 作用 | 力度 |
---|---|---|
| 建议:温和地告诉优化器:“请考虑使用这些索引。” | 最弱 |
| 强制:强烈建议优化器使用指定索引,基本等同于 | 中等 |
| 忽略:告诉优化器不要使用某些特定的索引。 | 强 |
注意:即使是 FORCE INDEX
,也不是绝对强制。如果查询无法使用你指定的索引(例如,你强制使用一个 a
列的索引,但 WHERE
子句里根本没有 a
列),MySQL 会报错(不会执行),或者在某些情况下会回退到全表扫描。它更像是一种“强烈建议”。
指定索引
EXPLAIN SELECT*
FROMusers USE INDEX ( idx_country )
WHEREcountry = 'USA' AND age > 25;
忽略索引
SELECT * FROM users IGNORE INDEX (idx_age)
WHERE country = 'Canada';
-- 这样优化器会在 idx_country 和全表扫描之间做选择,而不会考虑 idx_age
常用场景示例
假设我们有一张用户表 users
,其结构如下,并有几个索引:
CREATE TABLE `users` (`id` int NOT NULL AUTO_INCREMENT,`name` varchar(100) DEFAULT NULL,`email` varchar(100) DEFAULT NULL,`age` int DEFAULT NULL,`country` varchar(50) DEFAULT NULL,`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`id`),KEY `idx_country` (`country`),KEY `idx_age` (`age`),KEY `idx_name_email` (`name`,`email`), -- 复合索引KEY `idx_created_at` (`created_at`)
);
场景一:建议使用特定索引
优化器可能因为 country
的选择性不高而选择了其他索引或全表扫描,但你通过 EXPLAIN
分析后认为使用 idx_country
更快。
SELECT*
FROMusers USE INDEX ( idx_country )
WHEREcountry = 'USA' AND age > 25;
场景二:强制使用复合索引
如果你的查询条件完美匹配一个复合索引的前缀,可以强制使用它。
SELECT name,email
FROMusers FORCE INDEX ( idx_name_email )
WHEREname = 'John'
ORDER BYemail;
场景三:忽略一个索引
假设优化器错误地选择了一个效率不高的索引 idx_age
,而你认为全表扫描或者其他索引更合适,你可以先忽略这个索引。
SELECT * FROM users IGNORE INDEX (idx_age)
WHERE country = 'Canada';
-- 这样优化器会在 idx_country 和全表扫描之间做选择,而不会考虑 idx_age
场景四:在 JOIN 查询中指定索引
你也可以在连接表时指定索引。
SELECT *
FROM orders
FORCE INDEX (idx_user_id) -- 为 orders 表强制索引
JOIN users USE INDEX (PRIMARY) ON orders.user_id = users.id -- 为 users 表建议使用主键
WHERE users.country = 'UK';
总结与最佳实践
不要滥用:绝大多数情况下,MySQL 优化器能做出正确的选择。强制使用索引是一种高级优化手段。
先分析,后指定:总是先使用
EXPLAIN
分析原查询的计划,确认优化器是否选错了索引,然后再使用USE/FORCE INDEX
并再次用EXPLAIN
验证效果。关注数据变化:索引的最佳选择会随着表中数据的变化而变化。今天高效的索引提示,明天数据量增大后可能反而会变成瓶颈。
优先考虑优化索引本身:比起强制使用索引,更好的方法是:
检查索引设计是否合理(是否缺少某个高频查询的索引)。
使用复合索引来覆盖查询。
定期执行
ANALYZE TABLE table_name;
来更新表的统计信息,帮助优化器做出更准确的判断。