码迷,mamicode.com
首页 > 数据库 > 详细

数据库索引(二)聚集/非聚集索引,索引和锁

时间:2018-04-30 22:19:57      阅读:337      评论:0      收藏:0      [点我收藏+]

标签:mysql

聚集索引(InnoDB使用B+Tree作为索引结构

在一个结构中保存了b-tree索引和数据行;按照主键的顺序存储在叶子页上;

主键索引:叶节点存储(主键数据:所有剩余列数据)

二级索引(非聚簇索引):叶节点存储(索引列数据:主键数据)

非叶节点只存储 索引列

优点:

可以把相关数据保存在一起,如根据用户id聚集电子邮箱信息,只需要读取少数的数据页就能获取某个id用户的全部邮件;

数据访问更快,将索引和数据保存在同一个b-tree中;

使用覆盖索引扫描的查询可以直接使用页节点中的主键值;

缺点:

插入速度严重依赖于插入顺序,按照主键的顺序插入是加载数据到innodb表中速度最快的方式;

插入新行可能面临页分裂的问题,页分裂导致表占用更多磁盘空间;

通过二级索引需要两次查找,存储引擎找到二级索引的叶子节点获得对应的主键值,根据这个值去聚簇索引中找到对应的行

主键:

如果表没有什么数据需要被聚集(如上述邮件用户id),那么可以定义一个代理键作为主键,使用auto_increment自增列;

非聚集索引(MyISAM使用B+Tree作为索引结构

按照数据插入顺序存储在磁盘上,访问数据需要一次系统调用;

主键索引/二级索引:叶节点存储(索引列数据:数据在磁盘上的行号)

对比:

InnoDB提供事务支持事务,外键等功能;MyISAM不支持。

InnoDB支持行级锁;MyISAM只支持表级锁

InnoDB要求必须有主键;MyISAM允许没有任何索引和主键的表存在,索引都是保存行的地址。

覆盖索引

一个索引包含(或者说覆盖)所有需要查询的字段的值

覆盖索引要存储索引列的值,只能用b-tree索引做覆盖索引(不能用哈希索引,全文索引等)

优点:
1. MyISAM存储引擎在内存中只存储索引,覆盖索引不需要进行系统调用;

2. innodb存储引擎的聚簇索引机制,二级主键如果能覆盖查询,可以避免对主键索引的二次查询;

索引和锁

索引可以让查询锁定更少的行,innodb只有在访问行时才会对其加锁,而索引可以减少innodb访问的行数,从而减少锁的数量;

但是,只有当innodb在存储引擎层能够过滤掉不需要的行时才有效,如果无法过滤,那么在innodb检索到数据并返回给服务器层,mysql才能应用where语句进行过滤,而innodb已经锁住了这些行,直到服务器层过滤完成后释放锁;

如:select actor_id from sakila.actor where actor_id < 5 (范围)and actor_id <> 1 (过滤) for update;

执行explain命令,显示typerange,表示mysql为该查询选择的执行计划是索引范围查询,即在存储引擎层只执行了actor_id < 5的条件,查询结果:2,3,4;而被锁定的数据行:1,2,3,4

即使使用索引,也可能锁住一些不需要的行,但是不使用索引查找的话mysql会全表扫描并锁住所有的行。


数据库索引(二)聚集/非聚集索引,索引和锁

标签:mysql

原文地址:http://blog.51cto.com/13580976/2109313

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!