美文网首页
MySQL优化之索引基础,实战优化的基础知识

MySQL优化之索引基础,实战优化的基础知识

作者: javap | 来源:发表于2020-02-10 09:50 被阅读0次
    数据库设计总结

    1.尽量避免过度设计,例如会导致及其复杂查询的schema设计,或者有很多列的表设计。
    2.使用小而简单的合适数据类型,除非真实数据模型中有确切的需要,否则应该尽可能地避免使用NULL值。
    3.尽量使用相同的数据类型存储相似或相关的值,尤其是需要在关联条件中使用的列。
    4.注意可变长字符串,其在临时表和排序时可能导致悲观的按最大长度分配内存。
    5.尽量使用整形定义标识列。
    6.避免使用MySQL已经废弃的特性,例如指定浮点数的精度等。
    7.小心使用ENUM和SET。虽然他们用起来很方便,但是不要滥用,否则有可能变成陷阱。

    索引

    BTree索引,是一种树结构,索引速度比全表查询速度快。
    每个叶子节点即使MySQL中的一个页,默认每页16KB大小。
    MySQL中InnoDB使用B+Tree,B+Tree中每个叶子节点都有一个指向先一个叶子节点的指针。

    组合索引

    InnoDB中BTree索引生效的情况【customer创建组合索引(last_name, first_name, email)】
    匹配最左前缀:查找姓为MILLER的人,只使用索引的第一列。
    explain select * from customer where last_name='MILLER';
    全值匹配:全值匹配是指和索引中所有的列进行匹配,例如查找姓名为MARIA MILLER,email为MARIA.MILLER@sakilacustomer.org的人。
    explain select * from customer where last_name='MILLER' and first_name='MARIA' and email='MARIA.MILLER@sakilacustomer.org';
    匹配列前缀:可以匹配某一列值的开头部分,例如查找以M开头的姓的人。
    EXPLAIN select * from customer where last_name like 'M%';
    匹配范围值:查找姓大于等于WEINER的人。
    EXPLAIN select * from customer where last_name>='WEINER';
    精确匹配某一列并范围匹配另一列:查找所有姓为MILLER,且名字是字母M开头的人。即第一列last_name的全匹配,第二列first_name范围匹配。(也是前缀匹配)
    EXPLAIN select * from customer where last_name='MILLER' and first_name like 'M%';

    #如果不是按照索引的最左列开始查找,则无法使用索引【不从last_name列开始检索】
    explain select * from customer where first_name='MARIA'  and email='MARIA.MILLER@sakilacustomer.org';
    #不能跳过索引中的列【没有first_name列】
    explain select * from customer where last_name='MILLER' and email>'SHEILA.WELLS@sakilacustomer.org';
    #如果查询中有某个列的范围查询,则其右边所有列都无法使用索引优化查找【first_name为范围查找,email列无效】
    explain select * from customer where last_name='MILLER' and first_name>'MARIA'
                                           and email='MELANIE.ARMSTRONG@sakilacustomer.org';
    
    Hash索引,在MySQL中只有Memory引擎支持

    当Hash索引中出现哈希冲突的时候,存储引擎需要遍历链表中所有的行,找到所有符合条件的数据。
    冲突越多,索引代价越大。
    <=> 并非 <>
    Mysql 的 InnoDB引擎 有一个功能叫做“自适应哈希索引”。当MySQL发现某些索引值被频繁使用时,会在内存中基于BTree索引创建一个哈希索引。整个过程无法认为控制,仅可以通过innodb_adaptive_hash_index属性配置是否开启,默认开启该功能。

    InnoDB聚簇索引(主键索引)

    已满的页中,如果需要插入新的数据,会导致页分裂
    InnoDB二级索引



    Select id,name from tablename where name=’Rose’; #只需要遍历二级索引即可得到结果。

    Myisam引擎索引

    Myisam引擎中,主键索引与其他索引在结构上没有区别。

    InnoDB中默认最大填充因子是页的15/16大小 MySQL默认每页16K 数据达到15K的时候, 分配到下一页。 不同页之间可能不是顺序的,只是通过一个指针相连。

    InnoDB主键最好是连续递增的值,尽量避免使用UUID之类的长而无需的字符串。使用UUID做主键,在BTree的聚簇索引上,会导致插入速度慢,索引空间更大,其他二级索引空间也会更大。
    索引空间变大的原因有两个,一个是由于主键字段更长,其次是因为页分裂和碎片(页不饱和)导致。

    索引列的字段要尽可能小 因为BTree索引树高度页的大小以及页里面的数据大小决定的。数据越小,磁盘块存储的数据越多,树的高度越低,查询性能越高。

    三星索引:

    1、索引将相关的记录放到一起(Where子句后面的条件都可以使用索引,体现组合索引的利用)
    2、索引中数据的顺序和查找中的排列顺序一致(利用索引的有序性直接得到排序结果)
    3、索引中的列包含了查询中全部需要的列(利用索引中的值,直接得到查询结果,避免回表)

    相关文章

      网友评论

          本文标题:MySQL优化之索引基础,实战优化的基础知识

          本文链接:https://www.haomeiwen.com/subject/cuigxhtx.html