索引的使用

数据准备

# 执行前3步即可,因数据量庞大,创建时间可能超级长!!!可以另打开一个数据表用来查询数据个数

#1. 准备表
create table s1(
id int,
name varchar(20),
gender char(6),
email varchar(50)
);

#2. 创建存储过程,实现批量插入记录
delimiter $$ #声明存储过程的结束符号为$$
create procedure auto_insert1()
BEGIN
    declare i int default 1;
    while(i<300000)do
        insert into s1 values(i,'wuye','female',concat('wuye',i,'@blog'));
        set i=i+1;
    end while;
END$$ #$$结束
delimiter ; #重新声明分号为结束符号

#3. 调用存储过程
call auto_insert1();

#4. 查看存储过程
show create procedure auto_insert1\G 
创建30万条数据

使用索引前,不妨先自己查询一下看看执行时间,当索引创建成功后,再利用索引查询看一下时间对比啦!

索引介绍

# 索引的优势
    # 根据带有索引的字段查询速度非常快
# 索引的劣势
    # 创建索引同样占用磁盘空间,索引越多,占用内存越多
    # 索引越多,写入数据越慢
    # 删除索引并不会删除创建索引的数据结构,内存不会变小

 

# 索引的原理
    # block 磁盘预读原理
        # for line in f
        # 4096个字节
    # 读硬盘的io操作的时间非常的长,比CPU执行指令的时间长很多
    # 尽量的减少IO次数才是读写数据的主要要解决的问题

    # 数据库的存储方式
        # 新的数据结构 —— 树
        # 平衡树 balance tree - b树
        # 在b树的基础上进行了改良 - b+树
            # 1.分支节点和根节点都不再存储实际的数据了
                # 让分支和根节点能存储更多的索引的信息
                # 就降低了树的高度
                # 所有的实际数据都存储在叶子节点中
            # 2.在叶子节点之间加入了双向的链式结构
                # 方便在查询中的范围条件
        # mysql当中所有的b+树索引的高度都基本控制在3层
            # 1.io操作的次数非常稳定
            # 2.有利于通过范围查询
        # 什么会影响索引的效率 —— 树的高度
            # 1.对哪一列创建索引,选择尽量短的列做索引
            # 2.对区分度高的列建索引,重复率超过了10%那么不适合创建索引
索引原理

 

# 聚集索引和辅助索引
    # 在innodb中,聚集索引和辅助索引并存的
        # 聚集索引 -- 主键 更快
            # 数据直接存储在树结构的叶子节点
        # 辅助索引 -- 除了主键之外所有的索引都是辅助索引,稍慢
            # 数据不直接存储在树中
    # 在myisam中,只有辅助索引,没有聚集索引
聚焦索引和辅助索引

 

# 索引的种类
    # primary key,主键,默认创建聚集索引  约束的作用:非空 + 唯一
        # 联合主键
    # unique 自带索引 辅助索引   约束的作用:唯一
        # 联合唯一
    # index  辅助索引            没有约束作用
        # 联合索引
索引的种类

索引的创建与删除

# 创建单个索引   
    # 注意:如果表中数据越多,创建索引越慢,索引越多,占用磁盘空间越多,且写入数据越慢
create index 索引名 on 表名(需要创建索引的字段);
create index ind_id on t1(id);  # 在 t1 表为 id 字段 创建索引,索引名为 ind_id;

# 删除索引  注意:删除索引并不会删除创建索引的数据结构
drop index 索引名 on 表名;
drop index ind_id on t1;          # 在 t1 表中删除索引名为 ind_id 的索引;

# 创建联合索引
  # 注意:使用联合索引时要命中索引必须要有字段1,否则索引不生效
create index 索引名 on 表名(字段1,字段2...);

 

索引的命中

# 以email为条件查询
    # 不添加索引的时候肯定慢
    # 查询的字段不是索引字段,也慢
# id作为条件的时候
    # 如果不加索引,速度慢
    # 加了索引,速度快

# 索引不生效的原因
    # 要查询的数据的范围大
        # > < >= <= !=
        # between and
            # select * from 表 order by age limit 0,5;  # 使用limit 速度慢
            # select * from 表 where id between 1000000 and 1000005;  # 使用between速度快
        # like
            # 结果的范围大 索引不生效
            # 如果 abc% 索引生效,%abc索引就不生效
    # 如果一列内容的区分度不高,索引也不生效
        # name列
    # 索引列不能在条件中参与计算
        # select * from s1 where id*10 = 1000000;  索引不生效
        # select * from s1 where id = 1000000*10;  索引生效
    # 对两列内容进行条件查询
        # and and条件两端的内容,优先选择一个有索引的,并且树形结构更好的,来进行查询
            # 两个条件都成立才能完成where条件,先完成范围小的缩小后面条件的压力
            # select * from s1 where id =1000000 and email = 'wuye1000000@blog';
        # or or条件的,不会进行优化,只是根据条件从左到右依次筛选
            # 条件中带有or的要想命中索引,这些条件中所有的列都是索引列
            # select * from s1 where id =1000000 or email = 'wuye1000000@blog';
    # 联合索引  # create index ind_mix on s1(id,name,email);
        # select * from s1 where id =1000000 and email = 'wuye1000000@blog';
        # 在联合索引中如果使用了or条件索引就不能生效
            # select * from s1 where id =1000000 or email = 'wuye1000000@blog';
        # 最左前缀原则 :在联合索引中,条件必须含有在创建索引的时候的第一个索引列
            # select * from s1 where id =1000000;    能命中索引
            # select * from s1 where email = 'wuye1000000@blog';  不能命中索引
            # (a,b,c,d)
                # a,b
                # a,c
                # a
                # a,d
                # a,b,d
                # a,c,d
                # a,b,c,d
        # 在整个条件中,从开始出现模糊匹配的那一刻,索引就失效了
            # select * from s1 where id >1000000 and email = 'wuye1000001@blog';
            # select * from s1 where id =1000000 and email like 'wuye%';
索引是否生效
# 什么时候用联合索引
    # 只对 a 对abc 条件进行索引
    # 而不会对b,对c进行单列的索引

# 单列索引
    # 选择一个区分度高的列建立索引,条件中的列不要参与计算,条件的范围尽量小,使用and作为条件的连接符
# 使用or来连接多个条件
    # 在满上上述条件的基础上
    # 对or相关的所有列分别创建索引

# 覆盖索引
    # 如果我们使用索引作为条件查询,查询完毕之后,不需要回表查,覆盖索引
    # explain select id from s1 where id = 1000000;
    # explain select count(id) from s1 where id > 1000000;
# 合并索引
    # 对两个字段分别创建索引,由于sql的条件让两个索引同时生效了,那么这个时候这两个索引就成为了合并索引
各种索引的使用场景
# 执行计划 : 如果你想在执行sql之前就知道sql语句的执行情况,那么可以使用执行计划
    # 情况1:
        # 30000000条数据
            # sql 20s
            # explain sql   --> 并不会真正的执行sql,而是会给你列出一个执行计划
    # 情况2:
        # 20条数据 --> 30000000
            # explain sql
执行计划

 

# 索引的命中:
    # 范围,条件的字段是否参与计算(不能用函数)
    # 列的区分度(长度),条件and/or
    # 联合索引的最左前缀问题
# 建表、使用sql语句的时候注意的
    # char 代替 varchar
    # 连表 代替 子查询
    # 创建表的时候 固定长度的字段放在前面
注意

 

原文链接:https://www.cnblogs.com/Eva-J/articles/10126413.html#_label3

 

posted @ 2019-12-02 22:40  无夜。  阅读(321)  评论(0编辑  收藏  举报