1.前言:
索引,说白了就是一种数据结构,看过很多关于mysql索引的介绍都是形象生动地把它比较一般书的目录,比如说我们要想要看书中某一具体的章节,如果没有目录的话,我们只能从第一页一页一页地从前往后进行寻找了,这样的话就无比的麻烦且浪费时间,但是如果我们有目录的话,想要看某一具体章节,就可以直接先从目录中看到它的具体位置,然后直接瞬间就根据它的位置(页码)翻到了我们想要看到的具体章节了,这样既方便又节约了时间。
2.索引语句语法
想要学习索引,就要首先了解它的语法
1.创建索引 创建索引有两种方法,一种是我们在定义表结构(建表)的时候就指定索引,另一种就是在已经存在的表中添加索引 ##创建辅助索引(二级索引) alter table table_name add index idx_name(name) ##创建唯一索引 alter table table_name add unique index undix_name(name) ##创建复合索引 alter table table_name add index idx_name_age(name,age) ##创建前缀索引 alter table table_name add index idx_name(name(5)) 2.删除索引 alter table table_name drop index 索引名
3.索引应用规范
3.1建立索引的原则(DBA运维规范)
- 建表一定要有主键,一般是无关列,且自增长
- 经常做where条件列,order by , group by , join on ,distinct的条件
- 最好用唯一值多的列作为联合索引前导列,其他的按照联合索引细节优化来做
- 列值较长的索引列,一般建议使用前缀索引
- 降低索引条目,不要创建没有使用的索引,且清理掉常常不用的索引
- 索引维护一般要避开业务繁忙期
- 小表不建议建立索引
3.2不走索引的情况(开发规范)
- 没有查询条件或者查询条件没有建立索引
- 查询结果集是原表中的大部分数据,应该是在25%以上。
- 索引本身失效,统计数据不真实
- 查询条件使用函数在索引列上,或者对索引列进行运算,包括(+,-,*,/,!等)
- 隐式转换导致索引失效
- <>, not in() 不走索引(辅助索引)
- like "%aa"百分号在前面不走
4.联合索引的key_len的计算方式
- 所有的索引字段,如果设置有not null,则需要添加一个字节
- 定长字段,int占用4个字节,bigint占用8个字节,char(n)和varchar(n)占用n个字符
- date 是占3个字节,datetime占用8个字节,timestamp占用4个字节
- 对于变长varchar(n)类型,则有n个字符+2个字节
- 不同字符集,一个字符占用的字节数不同,latin编码的,一个字符占用一个字节;gbk编码的,一个字符占用两个字节;utf8占用3个字节,utf8mb4占用4个字节
这里要注意key_len只指示了where中用于条件过滤时被选中的索引列,是不包含order by/group by这一部分被选中的索引列的,所以可能存在排序用到索引但是key_len不对等的情况。
INNODB的索引会限制单独Key的最大长度为767字节,联合索引的单列项同样如此。