Mysql 索引知识点大全
Posted 栗子~~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql 索引知识点大全相关的知识,希望对你有一定的参考价值。
文章目录
前言
如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。
而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!
mysql 索引知识点大全
01 索引的基本介绍
01::01 定义
索引存在于对应的索引文件中,索引本质就是排好顺序的一组数据。
01::02 作用
(1) 在索引数据中进行排序,避免再次排序;
(2)在索引数据中对数据进行定位,避免全表扫描;
01::03 索引文件位置
(1)如果当前表依赖于INNODB存储引擎(yinqing),索引存在于FRM文件;
(2)如果当前表依赖于MYISAM存户引擎(yinqing),索引存在于MYI文件;
01::04 索引基本操作
(1)查看表文件中已存在的索引
show index from 表
(2)创建索引
create index 索引名 on 表名(字段名)
(3)删除索引
drop index 索引名 on 表名
02 索引的分类
02::01 聚簇索引与非聚簇索引
聚簇索引:
(1)只能来自于采用INNODB存储引擎表的数据。
(2)Mysql自动将采用了INNODB存储引擎表中主键建立索引,这个索引就是聚簇索引。
(3)如果当前表中没有主键,Mysql将会选择一个添加唯一性约束的字段作为聚簇索引。
(4)如果当前表中即没有主键字段,也没有添加唯一约束字段,Mysql将随机选取一个聚簇索引。
(5)在采用INNODB存储引擎的表文件中,必然会存在一个聚簇索引。
(6)在采用INNODB存储引擎的表文件中,只能有一个聚簇索引。
(7)在表文件中其他字段建立的索引都是非聚簇索引。
非聚簇索引:
(1)是由开发人员自行创建。
(2)对于采用了INNODB存储引擎表,除了一个聚簇索引之外,其他字段上创建的索引都是非聚簇索引。
(3)在采用MyIsam存储引擎的表中,创建的所有索引都是非聚簇索引。
聚簇索引与非聚簇索引的区别
(1)聚簇索引:数据节点存储的【当前数据所在行数】以及【当前数据所在数据行内容】。
因为聚簇索引的这个结构,所以在查询时可以直接在定位数据节点上,读取当前数据所在数据行中字段信息, 不需要使用I/O流到硬盘上表文件上进行读取。
(2)非聚簇索引:数据节点存储的只有【当前数据所在行数】。
由于数据节点存储的当前数据所在行数,没有其相关内容,所以定位之后,需要使用I/O流到硬盘上表文件中定位数据行其他字段内容,因此执行效率相对较慢。
02::02 主键索引、唯一索引、普通索引
主键索引:
如果当前表文件中字段添加主键约束,mysql主动的将当前字段上数据进行排序,其生成的索引称为主键索引。
唯一性索引:
如果当前表文件中字段添加唯一性索引,mysql主动的将当前字段上数据进行排序,其生成的索引被称为唯一性索引。
唯一性索引不包含null。
普通索引:
如果当前表文件中的字段上没有添加任何索引,此时在这个字段上创建的索引就是普通索引 。
执行效率:
主键索引>唯一性索引>普通索引
02::03 单个索引、复合索引
单个索引:
创建方式:create index 索引名 on 表名(字段名)
复合索引:
创建方式:create index 索引名 on 表名(字段1,字段2,字段3)
即多个字段同时建立一个索引,叫做联合索引。
数据排列方式:安装索引中字段的声明进行排序,先按照字段1来做排序,如果在字段1中出现重复的数据,根据这两个数据中的字段2来做排序,依次类推。
特点:联合索引最左匹配原则
假设现在建立了idx_test (group_id,cal_id,user_name_info)的联合索引,那么索引的排序为: 先按照group_id排序,如果group_id相同,则按照cal_id排序,如果cal_id的值也相等,则按照user_name_info进行排序;
当进行查询时,此时索引仅仅按照group_id严格有序,因此必须首先使用group_id字段进行等值查询,之后对于匹配到的列而言,其按照cal_id字段严格有序,此时可以使用cal_id字段用做索引查找。以此类推.因此在建立联合索引的时候应该注意索引列的顺序,一般情况下,将查询需求频繁或者字段选择性高的列放在前面.此外可以根据特例的查询或者表结构进行单独的调整。
where group_id = 5 and cal_id = 6 and user_name_info = “pomit” : (可以走索引idx_test,查询效率最高,索引全覆盖)
where cal_id = 6 and group_id = 5 and user_name_info = “pomit” : (可以走索引idx_test)
where group_id = 5 and cal_id = 6 : (可以走索引idx_test)
where group_id = 5 and user_name_info = “pomit” : (可以走索引idx_test)
where group_id = 5 : (可以走索引idx_test)
where cal_id = 6 : (不走索引idx_test)
where cal_id = 6 and user_name_info = “pomit” : (不走索引idx_test)
–多列索引在范围查询中应用
where group_id=? and cal_id between ? and ? and user_name_info=?;索引覆盖group_id和cal_id,因b列是范围查询,因此user_name_info列不能走索引。
where a=? and b between ? and ? and c=?;索引覆盖a和b,因b列是范围查询,因此c列不能走索引。
where a between ? and ? and b between ? and ? and c=?;a列走索引,因a列是范围查询,b列是范围查询也不能使用索引。
–多列索引在排序中应用
select * from test where a=? and b=? order by c;a、b、c三列全覆盖索引,查询效率最高。
select * from test where a=? and b between ? and ? order by c;a、b列使用索引查找,因b列是范围查询,因此c列不能使用索引,会出现file sort。
复合索引的好处:
1)减少索引建立的开销。建了一个(a,b,c)的复合索引,那么实际等于建了(a),(a,b),(a,b,c)三个索引,因为每多一个索引,都会增加写操作的开销和磁盘空间的开销。对于大量数据的表,这可是不小的开销!
2)覆盖索引。同样的有复合索引(a,b,c),如果有如下的select a,b,c from table where a=1 and b = 1。那么MySQL可以直接通过遍历索引取得数据,而无需回表,这减少了很多的随机io操作。减少io操作,特别的随机io其实是dba主要的优化策略。所以,在真正的实际应用中,覆盖索引是主要的提升性能的优化手段之一
3)缩小筛选范围。有1000W条数据的表,有如下select * from table where a = 1 and b =2 and c = 3,假设假设每个条件可以筛选出10%的数据,如果只有单值索引,那么通过该索引能筛选出1000W*10%=100w 条数据,然后再回表从100w条数据中找到符合b=2 and c= 3的数据,然后再排序,再分页;如果是复合索引,通过索引筛选出1000w *10% *10% *10%=1w,然后再排序、分页。
03 索引的使用规则
1、如果索引字段上 使用函数,导致索引失效
2、如果索引字段上 使用运算,导致索引失效
3、如果索引字段上 产生了隐式类型转换,导致索引失效
4、如果索引字段上 进行模糊查询,只支持前置条件的模糊查询
5、 字符集排序规则不一致导致表链接无法匹配索引
6、 where 条件有sysdate()导致无法匹配索引
对此,在mysql官方描述下,
由于sysdate()函数的不确认性,索引会失效。
建议:
使用NOW()
以上是关于Mysql 索引知识点大全的主要内容,如果未能解决你的问题,请参考以下文章