一、索引的使用规则

假设有一个SQL语句:
select * from table where a=1 and b=2 and c=3,要怎么建立索引,才可以确保这个SQL语句能使用到索引来进行查询?
答:引入索引最左前缀匹配原则的概念:与联合索引相关联,很多时候索引是针对几个字段来建立的;
假设要对一个商品表按照店铺、商品、创建时间三个维度来进行查询,那么就可以将这三个字段建立一个联合索引:shop_id、product_id、gmt_create;
create index (shop_id,product_id,gmt_create)

(1)全列匹配
假设你的sql语句里面,正好在where条件后用到了这3个字段,那么一定可以用到这个联合索引,如:
select * from product where shop_id=1 and product_id=1 and gmt_create=’2021-01-01 10:00:00’;

(2)最左前缀匹配
如果你的sql语句里面,正好用到了联合索引最左边的一个或者几个条件字段,那么也可以用上这个索引,在索引里查找的时候就用最左边的几列就行了,如:
select * from product where shop_id=1 and product_id=1;

(3)第一个字段匹配了,第二个没匹配就直接用了第三个字段
如:
select * from product where shop_id=1 and gmt_create=’2021-01-01 10:00:00’;
第一个字段shop_id匹配,第二个字段product_id没匹配,直接用了第三个字段gmt_create,则会按照第一个字段在索引中去擦护照,找完得到结果集后,根据第三个字段来过滤,第三个字段是不走索引的;

(4)包含函数
如:
select * from product where shop_id=1 and 函数(product_id)=2;
这个sql语句会根据shop_id在联合索引中进行查询;

二、索引的缺点以及注意事项

索引的缺点是:
(1)因为要占用磁盘空间,所以会增加磁盘消耗,同时高并发的时候频繁插入和修改索引,会导致性能损耗,建议创建少的索引;
(2)在创建索引的时候,要注意一个选择性问题,假设你的一个字段status的值只有0和1,那么对于status这个字段创建索引就没什么意义,因为你根据0或者1会搜索成一堆的记录,还要重新去筛选;
如果你有一个id字段,每条记录的id都不一样,这样的话建立索引的效果就很好,因为可以定位到唯一的一条记录,大大减少要扫描的数据量;
还有一种特殊的索引:前缀索引,加入某个字段的值是一个很长的字符串,如果要建立索引的话,最好对这个字符串的前缀来进行创建,一般前缀长度越长,选择性的值就越高。

三、总结

在互联网系统中,一般就是通过降低SQL的复杂度,让SQL非常简单就可以了,然后搭配InnoDB存储引擎自动创建的主键索引(聚簇索引),加上几个创建的联合索引,就可以覆盖一个表的所有SQL查询需求了。