其中,被指定的索引必须要有索引名。
官方提供的基础语法:
index_hint:
USE {INDEX|KEY}
[FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])
| IGNORE {INDEX|KEY}
[FOR {JOIN|ORDER BY|GROUP BY}] (index_list)
| FORCE {INDEX|KEY}
[FOR {JOIN|ORDER BY|GROUP BY}] (index_list)
其中index_list为索引名。
测试用表:
-
mysql> CREATE TABLE hints_test(col1 int,
-
-> col2 int,
-
-> col3 int,
-
-> KEY idx_1(col1),
-
-> KEY idx_2(col2),
-
-> KEY idx_3(col3));
-
Query OK, 0 rows affected (0.09 sec)
随机插入一些数据:
- mysql> SELECT * FROM hints_test;
- +------+------+------+
- | col1 | col2 | col3 |
-
+------+------+------+
-
| 1 | 2 | 3 |
-
| 2 | 2 | 3 |
-
| 2 | 3 | 3 |
-
| 3 | 3 | 5 |
-
| 3 | 1 | 2 |
-
| 2 | 1 | 1 |
-
| 2 | 3 | 3 |
-
| 4 | 4 | 4 |
-
| 6 | 5 | 3 |
-
+------+------+------+
-
9 rows in set (0.00 sec)
正常select(注,explain结果部分省略,下同)
- mysql> EXPLAIN SELECT col1, col2, col3
- -> FROM hints_test
- -> WHERE col1=1 AND col2=2\G
- *************************** 1. row ***************************
- table: hints_test
-
type: ref
-
possible_keys: idx_1,idx_2
-
key: idx_1
-
key_len: 5
-
ref: const
加一个复合索引
-
mysql> ALTER TABLE hints_test ADD INDEX idx_1_2(col1,col2);
-
Query OK, 0 rows affected (0.57 sec)
- Records: 0 Duplicates: 0 Warnings: 0
①指定使用idx_1_2索引
- mysql> EXPLAIN SELECT col1, col2, col3
- -> FROM hints_test
- -> USE INDEX (idx_1_2)
- -> WHERE col1=1 AND col2=2\G
- *************************** 1. row ***************************
- table: hints_test
- type: ref
- possible_keys: idx_1_2
- key: idx_1_2
- key_len: 10
-
ref: const,const
②忽略目前表中的三个索引
- mysql> EXPLAIN SELECT col1, col2, col3
- -> FROM hints_test
- -> IGNORE INDEX (idx_1_2,idx_1,idx_2)
- -> WHERE col1=1 AND col2=2\G
- *************************** 1. row ***************************
- table: hints_test
- type: ALL
- possible_keys: NULL
- key: NULL
- key_len: NULL
-
ref: NULL
再次正常select:
此时col2走了索引,而order by col3没有走索引。
- mysql> EXPLAIN SELECT col1, col2, col3
- -> FROM hints_test
- -> WHERE col2=2 ORDER BY col3\G
- *************************** 1. row ***************************
- table: hints_test
- type: ref
- possible_keys: idx_2
- key: idx_2
- key_len: 5
- ref: const
③忽略idx_2索引,此时全表扫描:
- mysql> EXPLAIN SELECT col1, col2, col3
- -> FROM hints_test
- -> IGNORE INDEX (idx_2)
- -> WHERE col2=2
- -> ORDER BY col3\G
- *************************** 1. row ***************************
- table: hints_test
- type: ALL
- possible_keys: NULL
- key: NULL
- key_len: NULL
- ref: NULL
④强制对order by语句使用idx_3索引:
- mysql> EXPLAIN SELECT col1, col2, col3 FROM hints_test
- -> FORCE INDEX FOR ORDER BY (idx_3)
- -> IGNORE INDEX (idx_2)
- -> WHERE col2=2
- -> ORDER BY col3\G
- *************************** 1. row ***************************
- table: hints_test
- type: index
- possible_keys: NULL
- key: idx_3
- key_len: 5
- ref: NULL
同理,除了WHERE和ORDER BY,可以同样对GROUP BY、JOIN操作进行USE、IGNORE、FORCE三种HINTS。
写法为:
(USE, FORCE, IGNORE) and by scope (FOR JOIN, FOR ORDER BY, FOR GROUP BY).
参考文档:
MySQL 5.6 Reference Manual 13.2.9.3 Index Hint Syntax
作者微信公众号(持续更新)
