本篇继续介绍有关索引的使用。
目录
一、SQL提示
二、单列索引和联合索引
三、覆盖索引
四、前缀索引
五、索引的使用原则
一、SQL提示
我们在使用索引来进行查询时,很有可能会出现一个字段中包含多个索引的情况,例如这里有一个name字段,该字段关联了两个索引
当我们根据这个字段进行查询时,这两个索引都有可能会用到 那为什么最后用了i_n_g这个索引呢?这是MySQL替我们选择的,那可不可以指定使用哪个索引呢?其实是可以的,我们只需要在查询时给MySQL一个提示,让其使用某个索引,但这仅仅只是提示,具体使用哪个索引,还需要MySQL自行进行评估选择。
下面我们再来进行一次前面的查询语句,并提示MySQL要使用 i_u_n这个索引
语法如下:
select 字段名 from 表名 use index(要使用的索引名) 查询条件
我们还可以提示MySQL要忽略某个索引,具体如下:
select 字段名 from 表名 ignore index(要忽略的索引名) 查询条件
我们也可以强制MySQL使用某个索引 ,具体如下:
select 字段名 from 表名 force index(要强制使用的索引名) 查询条件
二、单列索引和联合索引
在MySQL中,我们可以根据单个字段构建索引(单列索引),也可以根据多个字段共同创建索引。单列索引的结构为B+Tree,并根据这单个字段的值进行大小比较。
联合索引同样为B+Tree结构,它会先根据最左边的字段来建树,如果最左边的字段值相同,则会以后一个字段值进行比较,以此类推。
三、覆盖索引
前面的文章中我们介绍过索引可以根据存储方式 的不同分为聚集索引和二级索引,聚集索引的叶子节点中包含一整条记录,而叶子节点的值则只包含索引的字段和主键字段的值。因此,在使用二级索引来进行查询时,如果查询的字段不只有索引的字段和主键的字段,那么将会进行回表操作,但如果查询的字段包括在索引的字段和主键的字段里,那么将不会回表,直接就能返回查询结果,此时使用的索引就可以称之为覆盖索引。
例如,下面这条SQL
(该表包含id,name,age三个字段)
可以发现,这条SQL查询的字段除了索引的字段(name)和主键的字段(id)外,还有一个age字段,因此,该次查询回表了,该索引也就不是覆盖索引。
我们通过profile来查看一下此次查询的时间
接下来我们再删掉name字段的索引,然后再根据name和age字段来创建一个联合索引
此时我们再进行前面的查询语句,然后再通过profile查看一下执行时间
可以发现这次查询要更快一点,这是因为查询的字段全部包含在联合索引和主键的字段里了,此次次使用的索引为覆盖索引,不再回表了。因此,我们还可以得出一个经验:当查询的字段比较多时,尽量创建联合索引来形成覆盖索引,从而避免回表操作,增强查询的效率。
四、前缀索引
当我们对字符串类型的字段创建索引时,需要对该字段的值进行比较,而字符串的比较,需要比较字符串中的字符,如果字符串比较长的话,那么比较的时间就会比较长,例如“hello,word”和“hello,words”需要比较10次才能比较出结果,这样就会导致比较所消耗的时间较长,影响查询的性能,因此我们可以选择只取该字符串的前缀来进行比较,这样就能让比较消耗的性能更少一点。像这种只比较字符串前缀创建的索引就为前缀索引,下面我们来看一下如何创建前缀索引。
创建前缀索引的语法如下:
create index 索引名 on 表名(字段名(前缀长度))
这里有一个name字段 ,我们给它加上一个前缀索引:
此时,我们就给name字段创建好长度为5的前缀索引了。
这个前缀长度要怎么确定呢?我们可以枚举前缀的长度,并查看该长度的不重复的前缀占全部记录的比值,如果该比值在某个值以上就可以以该长度作为前缀长度,例如,我们以1作为前缀长度,然后我们通过MySQL查询比值,
可以发现这个比值较低,因此1不适合作为前缀长度 ,我们再来看一下2作为前缀长度
此时比值达到了1因此2适合作为前缀长度。
五、索引的使用原则
索引的使用会大大提升我们的查询效率,但索引并不是一定会生效,会有索引失效的情况场景出现,同时,索引也不一定就能提升查询效率,有时甚至还会降低我们的查询效率,因此正确的使用索引是尤为重要的,,下面我们来看一下索引使用时应遵循的原则。
- 创建索引的表的数据量尽可能多,且该表的查询操作占比要大于修改操作的占比。
- 对需要进行查询,排序,分组等操作的字段创建索引。
- 如果字段为字符串类型,应尽量根据情况创建前缀索引。
- 查询的字段多时,尽量创建联合索引,从而做到覆盖索引。
- 索引的数量不是越多越好,应当根据需求创建索引,不要不需要索引的字段也创建索引了
-
如果索引的字段不能存放null值,尽量再建表时对该字段进行not null约束,当MySQL知道哪个字段不含NULL值时,能够更好的确定使用哪个索引性能更好。