《MySQL技术内幕InnoDB存储引擎》 随手记(三)

第5章 索引与算法
    
    索引是应用程序设计和开发的一个重要方面,
    索引过多或过少都不是好的设计,如何设计数据库达到一个平衡点是门艺术。
    实际生产中,开发人员总是事后才想起添加索引,这是错误的开发模式。
    DBA往往不了解业务,事后想添加索引需要耗费时间去监控大量的SQL语句,
    在这种现实背景下,开发人员最应当作出改变,去了解索引,不仅知道数据的使用,
    也知道在何处添加索引。
    

    5.1 InnoDB存储引擎索引概述
        该引擎支持三种索引:   
            B+索引
            哈希索引
            全文索引            
        注意:hash索引机制是自适应的,不能人为生成。
            B+树索引不能找到具体的行,只能找到数据行所在的页。
            然后把页读入内存,在内存中进行查找具体数据行。
    
    5.2 数据结构与算法
        (B+树索引是最常见的索引数据结构与算法)        
        5.2.1 二分查找法
           记录内部有序,通过每次和中间值比较,跳跃式查找,
           每次缩减一半的范围,快速找到目标的算法。其算法复杂度为log2(n)
        5.2.2 二叉查找树和平衡二叉树
            二叉查找树:
                二叉查找树中,左子树的键值总小于根的键值,
                    右子树的键值总大于根的键值。
            平衡二叉树:
                先符合二叉查找树的定义,
                其次满足任何节点的两个子树的高度最大差为1,
                    若不满足需要通过一次或多次左旋和右旋来达到树新的平衡。
                二叉树多用于内存结构对象中,因此维护的开销相对较小。
    5.3 B+树
        (Balance查找树,为磁盘等直接存取设备服务)
        在B树上增加规定:
            叶子结点存数据,非叶子结点存指针
            所有叶子结点从左到右用双向链表记录
        内部排列:
            所有的记录都按键值的大小放在同一层的叶子节点上,
            各叶子节点之间有指针进行连接(非连续存储),形成一个双向链表。
            索引节点按照平衡树的方式构造,
            并存在指针指向具体的叶子节点,进行快速查找。
        5.3.1 B+树的插入操作
            B+ 树的插入必须保证插入后子节点中的记录依然排序
            (为了保持平衡可能需要做大量的拆分页(spit)操作
                通常情况下,左兄弟会被首先检查用来旋转操作
            优势:旋转操作使 B+ 树减少了一次页的拆分操作
        5.3.2 B+树的删除操作            
            B+ 树使用填充因子(fill factor)来控制树的删除变化
                50% 是填充因子可设的最小值
            B+ 树的删除操作同样也必须保证删除后的叶子节点中的记录依然排序         
    5.4 B+树索引
        (B+ 树索引的本质就是B+ 树在数据库中的实现)
            高扇出性(B+ 树的高度一般都在 2 ~ 4 层,查找某一键值只需要 2 到 4次 IO
            B+ 树索引可以分为 聚集索引(聚簇索引) 和 辅助索引(二级索引)
            其内部都是B+ 树,即高度平衡,叶子节点存放所有数据
            不同的是,聚集索引叶子节点存储着整行记录数据,辅助索引存储着聚集索引键值。
        5.4.1 聚集索引
            聚集索引就是按照表的主键构造一颗B+树,
            叶子节点存放的是整张表的行记录,可直接找到数据。
            将聚集索引的叶子节点称为数据页,数据按照主键顺序存放。
            聚集索引的存储并不是物理上连续的,而是逻辑上连续的。
        5.4.2 辅助索引
            页内不包含行的全部数据,而是相应行数据的聚集索引键。
        5.4.3 B+树索引的分裂
        5.4.4 B+树索引的管理
            1、SHOW INDEX命令得到结果的含义:
                Table:索引所在的表名
                Non_unique:如果显示的值是0,说明这个字段(列)是唯一索引,显示1表示非唯一索引
                Key_name:索引的名字,用户可以通过这个名字来执行DROP INDEX
                Seq_in_index:索引中该列的位置,单独一个列的索引就是1,如果复合索引就是从1开始递增
                Column_name:索引列的名称(字段名)
                Collation:列以什么方式存储在索引中,可以是A或者NULL。
                    B+树索引总是A,即排序的。
                    如果使用了Heap存储引擎,并且建立了Hash索引,这里的值就是NULL。
                    因为Hash根据Hash桶存放索引数据,而不是对数据排序
                Cardinality:索引的区分度,应该尽可能接近于1。
                Sub_part:是否是列的部分被索引。
                Packed:关键字然后被压缩,如果没有被压缩则为NULL
                NULL:是否索引的列含有NULL值,如果显示为Yes,则该列允许为NULL,如果留空没有值,则该列不允许NULL
                Index_type:索引的类型,InnoDB存储引擎只支持B+树索引,都显示BTREE
                Comment:列的注释
            2、Fast Index Creation(FIC):快速索引创建
            3、Online Schema Change(OSC):在线架构改变
    5.5 Cardinality值
        5.5.1 什么是Cardinality
            一个评估值,用于评估列是否需要添加索引的指示器,
            对应性别字段、地区字段等,他们均有低选择性特征。
            给这些字段添加索引完全没有必要。
        5.5.2 InnoDB存储引擎的Cardinality统计
            在存储引擎层通过采样的方法来完成更新。
            以下情况会更新Cardinality统计信息:
                表中1/16的数据发生过变化
                stat_modified_counter>2 000 000 000:发生变化的次数
    5.6 B+树索引的使用
        5.6.1 不同应用中B+树索引的使用
            应用场景有:
                OLTP:具体信息,一线业务。
                    通常给订单号等查找条件建立索引。
                OLAP:宏观的信息,而不是微观。
                    通常会需要对时间字段进行索引,
                    因为大多数统计需要根据时间维度进行数据筛查。
        5.6.2 联合索引
            对表上多个列进行索引,并且按照索引的顺序在B+树上进行排序,
            并且在orderby时如果按照索引的顺序排序,可以避免filesort。
            注意:单独看后面的列,并没有按顺序摆放,索引将不起作用。
            filesort是外部排序,可理解为使用状态机来实现归并排序,
            发生在根据某一个没有添加索引的字段进行排序,效率低。
            使用explian命令将在Extra中看到filesort。
        5.6.3 覆盖索引
            从辅助索引中就可以得到查询的记录,不需要查询聚集索引中的记录。
        5.6.4 优化器选择不使用索引的情况
            默认占比超20%会选择聚集索引(主键),放弃使用辅助索引。
            当要检出数据量大时,优化器会选择(全表扫描,顺序读)。
            在用固态硬盘(随机读快)并认为用辅助索引更快,可FORCE INDEX。
        5.6.5 索引提示
            若优化器错误地选择了某个索引,导致 SQL 语句执行过慢,
            可FORCE INDEX 用于强制指定某个索引完成查询。
        5.6.6 Multi-Range Read优化    
            MRR 优化适用于 range、ref、eq_ref 类型的查询。
            在查询辅助索引时,结果按照主键进行排序,在顺序查找聚集索引,
            减少缓冲池中页被替换的次数,批量处理对键值的查询操作。
        5.6.7 Index Condition Pushdown(ICP)优化
            原理:存储引擎层过滤
            当进行索引查询时,会在取出索引的同时过滤,减少了SQL层过滤
    5.7 哈希算法
        5.7.1 哈希表
            自适应hash索引,不只存在于自适应hash中,
            每个数据库中都存在,用来加速内存中数据的查找。
        5.7.2 InnoDB存储引擎中的哈希算法
            用于字典查找,哈希函数采用除法散列方法,
                冲突机制采用链表方式。
        5.7.3 自适应哈希索引(默认开启)
            通过参数innodb_adaptive_hash_index来禁用或启动此特性。
            属于数据库内部机制,DBA不能干预。
            它只对字典类型的查找非常快速,而对范围查找无效。
    5.8 全文检索
        5.8.1 概述
            使用倒排索引(inverted index)来实现。
            MyISAM存储引擎一直支持,InnoDB1.2.x起支持。
        5.8.2 倒排索引
            使用辅助表,单词与单词自身在一个或多个文档中所在位置之间的映射。
            通常利用关联数组实现。
        5.8.3 InnoDB全文检索
            三个限制:
                1.只能有一个全文索引
                2.全文检索索引必须相同的字符集和字符序
                3.不支持没有单词界定符的语言,如中日韩语等
        5.8.4 全文检索
            两种方法:
                自然语言(Natural Language)
                    默认方法,可省略:(IN NATURAL LANGUAE MODE)
                布尔模式(Boolean Mode):(IN BOOLEAN MODE)        
                    +: 该word必须存在
                    -: 该word必须排除
                    (no operator): 该word可选,如果出现,相关性更高
                    @distance: 查询的多个单词必须在指定范围之内
                    >: 出现该单词时增加相关性
                    <: 出现该单词时降低相关性
                    ~: 出现该单词时相关性为负
                    *: 以该单词开头的单词
                    ": 表示短语
    5.9 小结
        本章循序渐进学习了B+树、全文索引等原理,从数据结构入手,
        通过讨论了索引的环境和优化方法,分析在一些业务情景中优化索引方案的依据。
        

发布了103 篇原创文章 · 获赞 175 · 访问量 25万+

猜你喜欢

转载自blog.csdn.net/ai_64/article/details/104547426