今天突发想起来以前被问到各种索引会不会用到,一想到当时被问的转圈,本着只要我敢说,不管对错的原则,上来就是一堆胡扯,最终也是贻笑大方
本着程序员严禁的性格 怎么可以这样 所以在百忙之余自己尝试了各种可能
前提准备 一个表 然后要有索引 (这里有三个)
-- PRIMARY `id`
-- index01 `tenant_id`, `product_id`, `sales_qty`
-- index02 `tenant_id`, `mshop_id`, `product_id`, `product_spec_id`
借助mysql 的 EXPLAIN 查看执行计划判断是否真的可以用到索引
正文来了:
序号 | SQL |
执行计划(使用索引) | 解释 |
1 | EXPLAIN SELECT * from mshop_product where product_id='123' and tenant_id='123' |
index02 | where后面的字段 无顺序要求,sql解析器会自己排序的 |
2 | EXPLAIN SELECT id from mshop_product where product_id='596975389245446' and tenant_id='596814462189568' and id ='596975389245444' |
PRIMARY | 有id 肯定使用主键索引,但是如果id不存在就会全表扫描 |
3 | EXPLAIN SELECT * from mshop_product where tenant_id='123' and product_spec_id='123' and mshop_id ='123' |
index02 | 解释同1 |
4 | EXPLAIN SELECT id from mshop_product where mshop_id='123' and sales_qty='123' | 无 | 不能使用索引,全表扫描 |
5 | EXPLAIN SELECT * from mshop_product where id ='596975389245444' | PRIMARY | 主键索引,这个简单了 |
6 | EXPLAIN SELECT id from mshop_product where product_spec_id >=5 and product_spec_id<=999 | index02 | 都可以用到索引这两条sql主要判断 范围查询会不会用索引,不要被6迷惑,后面有详细解释 |
7 | EXPLAIN SELECT * from mshop_product where tenant_id>=100 and tenant_id<=200; |
index02 | |
8 | EXPLAIN SELECT * from mshop_product where tenant_id in (100,200,300,400) | index02 | in可以用索引 |
9 | EXPLAIN SELECT * from mshop_product where tenant_id not in (100,200,300,400) | 无 | not in 用不到索引 |
10 | EXPLAIN SELECT * from mshop_product where id not in (100,200,300,400) | PRIMARY | not in 在碰到主键时候 区服了 |
11 | EXPLAIN SELECT * from mshop_product where tenant_id not in (100,200,300,400) and mshop_id='123' | 无 | 不走索引了 |
12 | EXPLAIN SELECT id from mshop_product where product_spec_id='123' | index02 | 用到索引,应该是mysql强制使用了毕竟查了 可以进行索引覆盖 |
13 | EXPLAIN SELECT * from mshop_product where product_spec_id='123' | 无 | 找不到用索引的理由 |
本次试验到此暂时结束,主要试验了针对联合索引的乱序和跳跃等情况,并没有网上说的最左匹配那么无情,大部分都可以用到索引,同时针对部分sql在查询id和全部查询的时候也出现差异的情况,主要可能是mysql自己的内部逻辑,比较索引覆盖比全表扫描更快
如果有明白人也请评论下,帮帮兄弟