1. MySQL索引
索引是一种可以让SELECT语句提高效率的一种数据结构
索引的优缺点
优点:某些情况下使SELECT语句大幅提高效率,合适的索引可以优化MySQL服务器的查询性能,从而起到优化MySQL的作用
缺点:表行数据的变化(insert, update, delete),建立在表列上的索引也会自动维护,一定程度上会使DML操作变慢;索引会占用磁盘额外的存储空间
2. 索引基本原理
如果在stu表的sno列上创建索引alter table stu add index idx_sno(sno);
首先会提取stu表中所有记录sno的值,在内存中按照从小到大的顺序排序
排序后的结果形成了很多索引页(page),这个过程由mysql按照算法自动完成,不用过于深究其中的详细过程
索引页之间存在一定的关联关系,一般为树形结构;分为根节点、分支节点、和叶子节点
根节点页中存放分段sno的起始值,以及值所对应的分支索引页号
分支索引页中存放分段sno的起始值,以及值所对应的叶子索引页号
叶子索引页中存放排序后的sno值,该值所对应的表页号, 下一个叶子索引页的页号
sno建立索引后,执行select * from stu where sno=13查询过程如下:
第一步 索引页存在关联关系,先找索引页号20的根节点,13在>=11和<17的范围内,需要查找25号索引页
第二步 读取25号索引页,13在>=11和<14范围内,得到了26号叶子索引页
第三步 读取26号叶子索引页,找到了13这个值,以及该值所对应表页的页号161,因为是select * 所有列,目前只得到了sno的值,还要得到sname,sex,height等,因此需要再读一次编号为161的表页,里面存放了sno之外的值
sno建立索引后,执行select * from stu where sno=13查询过程如下:
第四步 读取161号表页,获得sname,sex,height等值
以上4步,只读取了3个索引页1个表页,共4个页,比读取所有表页(5000个页),按照sno=13挨个翻一遍效率要高,这也是有些情况下索引可以加速查询的原因
3. 创建索引
给表列创建索引
建表时创建索引
create table t(id int,name varchar(20),index idx_name (name));
给表追加索引
alter table t add unique index idx_id(id);
给表的多列上追加索引,以下2种方式均可
alter table t add index idx_id_name(id,name); --drop index idx_id_name on t;
create index idx_id_name on t(id,name);
4. 查看索引
查看表列上的索引索引,以下2种方式均可
show index from t;
show keys from t; --mysql中索引也被称为keys
使用show create table语句查看t表列上的索引:
show create table t\G
5. 删除索引
使用alter table命令删除索引
alter table 表名 drop index 索引名
alter table t drop index idx_id;
使用drop index命令删除索引:
drop index 索引名 on 表名
drop index idx_name on t;
drop index idx_id_name on t;
6. 索引使用条件和弊端
大表(记录数多),仅从中找出少量行(总行数的3%-%5)
例如:100万个学生中,学号是主键没有重值,仅找1个学生,在学号列上加索引并按照学号来查找会很快找到
例如:100万个学生中,学号1到100万,要找学号大于1的学生,这样99%以上的结果都会返回,此时索引没有作用,不能起到加速查询的作用
在经常作为查询条件(where)的列上添加索引,返回记录少,就可能用上索引,起到加速查询的作用
索引和表的区别是索引页之间存在关联关系,但是会占用额外的磁盘空间,有可能出现索引占的磁盘空间比表还大的情况
例如:在表上根据常用查询条件,使用多个列建立了索引
索引会自动维护,常规的DML操作会导致索引的变化,这会增加服务器的负担,导致DML操作变慢,尤其是一个表有多个索引的情况下