开篇
在上一篇文章中,我们有一个表,里面的内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| mysql> select * from org_copy; + | org_id | org_name | org_parent_id | org_copy | + | 1 | 一级部门 | 0 | 1 | | 2 | 一一级部门 | 0 | 2 | | 3 | 1.1级部门 | 1 | 3 | | 4 | 1.2级部门 | 1 | 4 | | 5 | 1.1.1部门 | 3 | 5 | | 6 | 1.1.2部门 | 3 | 6 | | 7 | 1.1.1.1部门 | 5 | 7 | | 8 | 1.3部门 | 1 | 8 | | 9 | 1.2.1部门 | 4 | 9 | + 9 rows in set (0.00 sec)
|
这应该是一个很基本的一个mysql表,同时我们在上一篇文章中,也执行了如下SQL。
1 2 3 4 5 6 7 8
| mysql> explain SELECT * FROM org_copy WHERE org_name>'一级部门' and org_parent_id=1; + | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | + | 1 | SIMPLE | org_copy | NULL | range | index_name | index_name | 768 | NULL | 1 | 11.11 | Using index condition | + 1 row in set, 1 warning (0.00 sec)
|
那么如果此时我们换一个SQL来进行查询呢?
1 2 3 4 5 6 7
| mysql> explain SELECT * FROM org_copy WHERE org_name>'1' and org_parent_id=1; + | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | + | 1 | SIMPLE | org_copy | NULL | ALL | index_name | NULL | NULL | NULL | 9 | 11.11 | Using where | + 1 row in set, 1 warning (0.00 sec)
|
此时是不是会一脸疑惑…为啥我的这个SQL,明明一样呀,但是为啥第一个就可以走索引呢???
因为在mysql里面,会判断当前where条件查询的数据量
,由于索引是由一个B+
树的形式存在,所以当通过org_name
来进行比较筛选的时候,是可以很快的定位出大致需要查询的数据量。
而当数据量大于30%的时候,mysql就会采用一种全表扫描的方式来进行查询,这也就是为什么不建议在区分度低的字段上建立索引了,假设一个字段只有三个值或者两个值,那么极有可能mysql会直接通过全表扫描的方式进行查询。
索引覆盖
这个是mysql调优中经常忽略的一点,由于mysql在建立索引的时候会一次性将索引字段存入到索引树中,所以如果我们的where
条件中所包含的字段均可以在索引中找到的话,那么mysql就会直接从索引中去取数据,而不会进行回表。例如如下SQL:
1 2 3 4 5 6 7 8
| mysql> explain SELECT org_parent_id FROM org_copy WHERE org_copy=1; + | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | + | 1 | SIMPLE | org_copy | NULL | ALL | NULL | NULL | NULL | NULL | 4325 | 10.00 | Using where | + 1 row in set, 1 warning (0.00 sec)
|
由于org_copy
字段非索引,所以此时只能是通过回表的方式进行查询。
总结
- 由于mysql会在数据量大于
30%
的时候进行全表扫描,所以最好就是不要在区分度低的字段上建立索引,避免进行了全表扫描。
- 对于过滤字段的使用,应该是尽最大的努力让
SQL
采用索引覆盖,如果无法避免的话就尽量让最左原则生效。进而加快查询速度。