MySQL3种指定索引的方式
在使用MySQL进行查询时,我们经常会遇到SQL执行没有按照我们预想的那样去使用某个索引优化查询,那怎么解决这个问题呢?
对于这个问题,MySQL给我们准备了三个方法,这三个方法可以帮助我们让SQL执行按照我们预想的那样去选择索引。今天我们就针对这三个方法分别来说说吧!
- use index:在你查询语句表名的后面,添加use index来提供你希望mysql去参考的索引列表,就可以让mysql不再考虑其他可用的索引。如:select * from table use index(name,age);
- IGNORE INDEX: 提示会禁止查询优化器使用指定的索引。在具有多个索引的查询时,可以用来指定不需要优化器使用的那个索引,还可以在删除不必要的索引之前在查询中禁止使用该索引。如:select * from table ignore index(name,age);
- force index:强制mysql使用一个特定的索引。一般情况下mysql会根据统计信息选择正确的索引,但是当查询优化器选择了错误的索引或根本没有使用索引的时候,这个提示将非常有用。
注意:use/ignore/force index(index) 括号里的index是索引名,而不是列名。而且后面必须要加上where条件
现在我们已经了解了MySQL提供的指定索引的三个方法,接下来我们就针对这三个方法来实验一下具体的操作及结果吧!
explain
SELECT
id,
org_code,
org_id,
create_time,
update_time
FROM
db.t_data
-- ignore INDEX( -- 忽略索引
force INDEX( -- 强制使用索引
-- use INDEX( -- 推荐使用索引
medicare_settle_time_IDX
, refund_settle_flag_IDX
, is_local_reconcile_IDX
)
WHERE
is_deleted = 0
AND (medicare_settle_time >= '2024-03-01 00:00:00'
and medicare_settle_time <= '2024-03-01 23:59:59'
AND refund_settle_flag = '0'
AND is_local_reconcile = 1
AND org_id = 20001001
AND campus_id = 30001002
)
ORDER BY
id ASC,
medicare_settle_time asc -- 这里至关重要,假如之前一直只能命中主键,此时则可以命中二级索引
LIMIT 3600, 112;
由于我想命中基于medicare_settle_time字段的索引,而不是主键,所以我追加了排序字段medicare_settle_time,只需要再mybatisplus中增加一个排序项即可
总结一下:
1,【use index】没有指定索引会导致全表扫描,指定的索引关联的字段不在where条件中依然不使用索引,导致全表扫描。所以指定索引时注意索引关联的字段是否在where条件中。
2,【ignore index】必须设置索引名,否则会报错。禁用的索引一定导致索引失效,即使使用【use index】重新指定该索引也无效
3,【force index】必须指定索引名。强制指定的索引关联的字段不在where条件中,所有索引都将失效。而且不能与【use index】同时使用
学习使我充实,分享给我快乐!