zoukankan      html  css  js  c++  java
  • 索引

    索引

    什么是索引?

             索引在MySQL中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构

    为何使用索引?

             加快查询速度

    索引的本质?

             通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据。

    索引的数据结构?

             b+树应运而生(B+树是通过二叉查找树,再由平衡二叉树,B树演化而来)。

    b+树性质

             1.索引字段要尽量的小,原因:使用大数量项会使磁盘块可存储数据数量变少,从而增高b+树的高度,使io次数变多

             2. 索引的最左匹配特性

    聚集索引与辅助索引

             相同:不管是聚集索引还是辅助索引,其内部都是B+树的形式,即高度是平衡的,叶子结点存放着所有的数据。

             不同:叶子结点存放的是否是一整行的信息

    聚集索引

             如果未定义主键,MySQL取第一个唯一索引(unique)而且只含非空列(NOT NULL)作为主键,InnoDB使用它作为聚簇索引。

             如果没有这样的列,InnoDB就自己产生一个这样的ID值,它有六个字节,而且是隐藏的,使其作为聚簇索引。

             由于实际的数据页只能按照一棵B+树进行排序,因此每张表只能拥有一个聚集索引。在多少情况下,查询优化器倾向于采用聚集索引。因为聚集索引能够在B+树索引的叶子节点上直接找到数据。此外由于定义了数据的逻辑顺序,聚集索引能够特别快地访问针对范围值得查询。

             好处:

             1.它对主键的排序查找和范围查找速度非常快,叶子节点的数据就是用户所要查询的数据。如用户需要查找一张表,查询最后的10位用户信息,由于B+树索引是双向链表,所以用户可以快速找到最后一个数据页,并取出10条记录

             2. 范围查询(range query),即如果要查找主键某一范围内的数据,通过叶子节点的上层中间节点就可以得到页的范围,之后直接读取数据页即可

    辅助索引

             表中除了聚集索引外其他索引都是辅助索引(Secondary Index,也称为非聚集索引),与聚集索引的区别是:辅助索引的叶子节点不包含行记录的全部数据。

             叶子节点除了包含键值以外,每个叶子节点中的索引行中还包含一个书签(bookmark)。该书签用来告诉InnoDB存储引擎去哪里可以找到与索引相对应的行数据。

            

    索引管理

             联合索引:

        -PRIMARY KEY(id,name):联合主键索引

        -UNIQUE(id,name):联合唯一索引

    -INDEX(id,name):联合普通索引

    创建,新增索引方式:

    #方式一

    create table t1(

        id int,

        name char,

        age int,

        sex enum('male','female'),

        unique key uni_id(id),

        index ix_name(name) #index没有key

    );

    #方式二

    create index ix_age on t1(age);

    #方式三

    alter table t1 add index ix_sex(sex);

    测试索引

    1. 一定是为搜索条件的字段创建索引,比如select * from s1 where id = 333;就需要为id加上索引

    2.在表中已经有大量数据的情况下,建索引会很慢,且占用硬盘空间,建完后查询速度加快

    3. 需要注意的是:innodb表的索引会存放于s1.ibd文件中,而myisam表的索引则会有单独的索引文件table1.MYI

    正确使用索引

             1 范围问题,或者说条件不明确,条件中出现这些符号或关键字:>、>=、<、<=、!= 、between...and...、like(使用%开头时)

             2 尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录

             3 =和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式

             4 索引列不能参与计算

             5 and/or

             6最左前缀匹配原则

             注意事项:

             - 避免使用select *

             - count(1)或count(列) 代替 count(*)

             - 创建表时尽量时 varchar 代替 char

             - 表的字段顺序固定长度的字段优先

             - 组合索引代替多个单列索引(经常使用多个条件查询时)

             - 尽量使用短索引

             - 使用连接(JOIN)来代替子查询(Sub-Queries)

             - 连表时注意条件类型需一致

             - 索引散列值(重复少)不适合建索引,例:性别不适合

    联合索引

             Create index inx_xxx on s1(email,name,gender,id);

    覆盖索引

             InnoDB存储引擎支持覆盖索引(covering index,或称索引覆盖),即从辅助索引中就可以得到查询记录,而不需要查询聚集索引中的记录。

    查询优化神器-explain

             explain select * from userinfo3 where name='alex'

  • 相关阅读:
    在IT行业工作如何获得高薪?选择前沿的技术,把准方向,有技术有人缘
    如何去做不想做的事情的 - 10个建议
    如何去做不想做的事情的 - 10个建议
    项目管理
    项目管理
    Spring Quartz 定时任务
    Spring Quartz 定时任务
    Spring @Transactional (一)
    Spring @Transactional (一)
    Search Insert Position
  • 原文地址:https://www.cnblogs.com/luck-L/p/9392847.html
Copyright © 2011-2022 走看看