索引

索引

什么是索引?

         索引在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'

posted @ 2018-07-30 21:22  luck_L  阅读(189)  评论(0编辑  收藏  举报