• day--41 mysql索引原理与慢查询优化


                            mysql索引原理与慢查询优化
    一:什么是索引
        01:索引的出现是为了提高查询数据的效率
        02:索引在mysql叫做“键” 或则“key“(primary key,uniquekey ,还有一个index key),是存储引擎用于快速找到记录
            的一种数据结构。索引能减少io次数,加速查询(primary key 和unique key ,除了有加速查询的效果外,还有约束的效果,
            primary key 不为空且唯一,unique key唯一,而index key 只有加速查询的效果,没有约束效果)
        03:优缺点:索引太多,应用程序的性能会受到影响,索引太少,对查询性能又会产生影响,需要找到一个平衡点。应该在一开始在
            需要的地方添加索引。
    
        04:索引的原理:
            索引时在没有数据的时候先建立索引然后再往里面添加数据,这样数据在查找的时候就能不断缩小需要查找的数据的范围了,索引就像
            是书的目录。在不断添加数据后,索引的能增加查询效率。但是会降低写入效率(一旦有新的数据块写入,原来的索引就没用了。需要
            重新建立索引。)
    
            索引的影响:01:在表中有大量的数据的前提下,创建索引速度会很慢
                       02: 在创建索引后,对表的查询速度会大幅度提升,但是写性能会降低。
            索引的本质:通过不断缩小想要的数据的范围来筛选出最终想要的结果,同时把随机事件变成顺序时间,也就是说,有了索引机制,可以
            总是用同一种查找方式来锁定数据。
    二:磁盘I/O与预读
        磁盘读取数据是靠机械运动,每次读取数据花费的时间由寻道时间(磁臂移动到磁道所用的时间),旋转时间(磁盘转速)和 传输时间
        (将数据从磁盘读取或则写入)三个部分。每次访问磁盘需要花费很多时间(相对于cpu处理数据的速度)。所以考虑到io操作每次读取数据占用的
        时间大小,计算机操作系统做了优化,当一次io操作的时候,不光把当前磁盘地址的数据,还把相邻的数据也都读取到内存缓冲区内。
        因为局部预读性原理告诉我们,当计算机访问一个地址的数据的时候,与其相邻的数据也会很快被访问到。每一次IO读取的数据我们称之为一页(page)。
        具体一页有多大数据跟操作系统有关,一般为4k或8k,也就是我们读取一页内的数据时候,实际上才发生了一次IO,这个理论对于索引的数据结构设计非常有帮助。
    三:索引的数据结构
       说明:b+数主要是为了磁盘读取查找数据出现的。(树形演示)
        索引的结构就是为了减少io,加速查询。索引的数据结构是 ”b+树(B+树是通过二叉查找树,再由平衡二叉树,b数演化而来。)”
    
    
       01:b+树查找过程

    02:b+树的性质:
        01:索引字段要尽量的小
                io次数主要取决于b+数的高度,高度越低,io查询的次数就越少。
           02:索引的最匹配特性
                就是要查找的数据,先从数据块的最左边开始查询,再匹配右边的
    四:聚集索引和辅助索引
    01:聚集索引 说的就是mysql的数据的主键。innodb存储引擎的表必须要有一个主键。
    myisam存储引擎在创建表的时候会生成三个文件:
            .frm (存储表的结构)
                .myd(是数据文件)
                .myi(索引文件)
            innodb存储引擎创建表的时候会生成两个文件
           .frm(存储结构)
                .idb(存储数据和索引)
    
    
         创建innodb存储引擎的表时,就需要给表一个主键,那么innodb引擎在存储数据的时候就默认按照索引的树形结构来保存。这种索引就是
            聚集索引。这样做主要是为了加快查询速度。
        02:在数据库中,B+树的高度一般是2--4层,也就是说查找一个键值的行记录最多只需要2到4次io,因为当前的机械硬盘至少可以做100次io
    2--4次的io意味着查询的时间只需要0.02---0.04秒
         数据库中的B+树索引可以分为聚集索引和辅助索引
            聚集索引和辅助索引相同的是:两者内部都是b+数的形式,高度是平衡的,叶子结点存放着所有的数据
            聚集索引和辅助索引的不同点是:叶子结点是否存放的是一整行的信息。
        03:聚集索引
          优点:01:对主键的排序查找和范围查找速度非常快,叶子结点的数据就是用户需要的数据。
                  02: 范围查询 : 如果需要查找主键某一范围的数据,通过叶子结点的上层中间结点就可以得到页的范围,之后直接读取数据页即可
        04:辅助索引:
      表中除了聚集索引外其他索引都是辅助索引(Secondary Index,也称为非聚集索引)(unique key啊、index key啊),
        与聚集索引的区别是:辅助索引的叶子节点不包含行记录的全部数据
    
    
    五:mysql索引管理
       01:索引的功能是快速查找
        02:mysql中德primary key unique,联合唯一都是索引,这些索引除了加速查找以外还有约束功能
        03:常用的索引
            001:普通索引index: 加速查找
            002:唯一索引:
                        主键索引 primary key :加速查找和约束
                        unique(id,name) :联合唯一索引
                        index(id,name):联合普通索引
    
        04:建立索引删除索引
            创建索引三种方法:
                001:alter table 表名 add primary key(需要加索引的字段) (eg:  alter table t1 add primary key(id)  给t1表的id加索引)
                002:create index  索引名  on  表名(字段名)(eg: create index ix_id  on t1(id)  给t1表的id加索引)
                003:创建表时给其加索引
                    create table 表名(
                                字段名1 数据类型  完整约束条件
                                字段名2 数据类型  完整约束条件
    
                                索引名   字段名3(长度)
                                        );
                    例子:
                    create table t1(
                                id int,
                                name char,
                                age int,
                                sex enum("male","female"),
                                unique key uni_id(id),
                                index ix_name(name)   #index 没有key
                    );
    
            删除索引:
                drop index 索引名字 on 表名字
    六:测试索引
    1:准备表
    create table s1(
                id int,
                name varcahr(20),
                gender cahr(6),
                email varchar(50)
            );
        2:创建存储过程,实现批量插入数据
        delimiter //
            create procedure auto_insert()
            begin
                decalare i in default 1;
                while (i<3000000) do
                    insert into s1 values(i,"TOM","male",concat("TOM",i,"oneboy"));
                    set i=i+1;
                end while;
            end //
            delimiter ;
        3:查看存储过程
    show create procedure auto_insertG
        4:调用存储过程
     call auto_insert();
    
    
    总结:
            #1. 一定是为搜索条件的字段创建索引,比如select * from s1 where id = 333;就需要为id加上索引
    
            #2. 在表中已经有大量数据的情况下,建索引会很慢,且占用硬盘空间,建完后查询速度加快
            比如create index idx on s1(id);会扫描表中所有的数据,然后以id为数据项,创建索引结构,存放于硬盘的表中。
            建完以后,再查询就会很快了。
    
            #3. 需要注意的是:innodb表的索引会存放于s1.ibd文件中,而myisam表的索引则会有单独的索引文件table1.MYI
    
            MySAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在innodb中,表数据文件本身就是按照B+Tree(BTree即Balance True)
            组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此innodb表数据文件本身就是主索引。
            因为inndob的数据文件要按照主键聚集,所以innodb要求表必须要有主键(Myisam可以没有),如果没有显式定义,则mysql系统会自动选择一个
            可以唯一标识数据记录的列作为主键,如果不存在这种列,则mysql会自动为innodb表生成一个隐含字段作为主键,这字段的长度为6个字节,
            类型为长整型.
    
    
    









  • 相关阅读:
    win10安装node后npm 报错
    nodejs 图片的像素级别处理
    vue 等比例截图组件,支持缩放和旋转
    撸一个 vue 的截图组件,按比例截取
    原生 js 录屏功能
    Mongodb命令行导入导出数据
    Linux 下配置 iSCSI 客户端
    基于 Docker 实现 DevOps 的一些探索
    10 张图带你深入理解 Docker 容器和镜像
    浅谈 Docker 安全合规建设
  • 原文地址:https://www.cnblogs.com/one-tom/p/10146361.html
Copyright © 2020-2023  润新知