Mysql数据库 —— 索引

重点

  • 索引
  • 事物
  • 调优
  • mvcc
  • 存储引擎
  • 主从复制
  • 读写分离
  • 分库分表
  • 日志系统

索引

红黑树和AVL树

二叉平衡树:二叉搜索树的一种,追求绝对平衡也就是任何一个左子树和右子树高度小于1
红黑树:二叉平衡树的一种,他不追求高度小于1

什么是索引

排好序的数据结构
每个节点(磁盘块)可以存16K数据,mysql索引一般3到4层就足以支撑千万级别的表查询。所以创建索引的字段短一些好,这样每个节点就存储更多指针。

B树和B+树的区别

相同点:它是一种二叉平衡树的一个种类,可以使查找时间为二分查找,O(logN)。多叉平衡树,每个节点(磁盘块)存储多个数据让数更矮,每个节点可以存16K数据

  1. 存储内容:B树的每个结点都存储了key和data,B+树的data存储在叶子节点上。节点不存储data,这样一个节点就可以存储更多指针。可以使得树更矮。查找更快
  2. 查找速度:b+数的根节点存储的指针一般常驻内存,所以查找速度非常快
  3. 稳定性:b+树查询的数据都在最底层的叶子节点,因此b+树查找更稳定
  4. 范围查找:b+树最底层叶子树节是排好序的,并且每个字节点使用双向指针连接,范围查找很快

为何使用B/B+树而不使用hash索引

hash结构:hash算法(MD5,crc16等算法的统称),会在底层做一次hash运算,把hash运算结果和字段索引地址关联,使用哈希一次运算就可以通过我们的索引找到数据地址。那么我们使用哈希查找速度更快,但是实际使用中我们没有使用哈希。
原因: 范围查找,hash索引没法支持:B+树他最底层数据节点是双向指针,找到了某个值,然后直接向后查找,找到范围。

我们在创建表的时候用代理主键还是自然主键

代理主键:和数据无关的列
自然主键:和数据相关的列
比如身份证信息,我们可以用身份证号作为主键(自然主键),也可以再创建一个id号作为主键(代理主键)。那么我们用哪个好:
用id的话占用更小空间,身份证号占用空间太大。所以使用代理主键更好

为何索引主键设置自增

当我们新建一行数据,当插入索引时,因为我们叶子结点是有序双向链表,如果索引自增,那么我们直接后增加节点。
但是如果非自增,我们要保持有序,那么我们就往前插入节点,后面的节点分页结构就会变化。维护成本太高,性能就会降低。

聚簇索引和非聚簇索引

https://www.jianshu.com/p/fa8192853184

  • 聚簇索引:索引和数据存储在一块。innodb的主键索就都是聚簇索引
  • 非聚簇(稀疏)索引:索引和数据分开存储,由每个索引指向数据对应的位置。

非聚簇索引的两种形式:

  1. myisam非聚簇索引:索引和数据分开。每个索引存储一个对应的数据空间的地址。每次先在索引中搜索对应索引,然后再去对应的数据存储地址空间查找数据。myisam的辅助索引也和主键索引查找方式一样。

  2. innodb的二级索引(辅助索引,普通索引)也是非聚簇索引但他和myisam的非聚簇索引不同,他是需要二次查找的。因为二级索引叶子结点存放的是主键的值,所以需要根据根据索引做一次回表操作,查询到真实数据。也就是需要二次查找。所以他的查询效率要低于聚簇索引。但是他的维护成本要低一些,比如我要修改某个数据,我们不需要改动索引
    二级索引举例:
    比如我们一个数据表主键索引是id。然后我们的二级索引是name,当我们对name进行条件搜索的时候需要两步:第一步:在辅助索引的B+树种找到对应的主键索引也就是ID。第二步:再使用主键索引在主键索引B+树种查询到对应数据(回表)。

区别:

  1. 聚簇索引的索引指针和数据存储在一起,速度更快。而非聚簇索引需要二次查找速度更慢
  2. 聚簇索引维护成本高,当插入数据的时候,如果需要分页,也就是插入数据导致的不同节点块分开,这时必须移动对应的数据。而非聚簇索引只需要分割索引,数据不需要移动,因为有指针指向数据地址。

innodb相对于myisam区别

innodb和myisam都是形容数据库表的引擎。

  1. 索引:InnoDB(索引组织表)使用的(聚集)聚簇索引,通过主键索引效率很高。InnoDB必须要有主键索引,没有主键索引他无法生成索引数据表。 MyISAM(堆组织表)使用的是非聚簇(稀疏)索引。索引和数据分离。要重定位一次。
  2. MyISAM的索引和数据是分开的,并且索引是有压缩的。内存使用率就对应提高了不少。能加载更多索引,而Innodb是索引和数据是紧密捆绑的,没有使用压缩从而会造成Innodb比MyISAM体积庞大不小。
  3. 事物:innodb支持事物,myisam不支持,这是选择innodb很大的一个原因,因为一旦数据插入错误就回滚
  4. 锁 myisam只支持表级锁,而innodb支持行级锁,表锁
  5. 外键innodb支持外键,myisam不支持

什么是联合(复合)索引

你得知道最左前缀匹配原则,这个东西是跟联合索引(复合索引)相关联的,就是说,你很多时候不是对一个一个的字段分别搞一个一个的索引,而是针对几个索引建立一个联合索引的。
举个例子,你如果要对一个商品表按照店铺、商品、创建时间三个维度来查询,那么就可以创建一个联合索引:shop_id、product_id、gmt_create
所以你一般来说不是就建立3个索引,一般来说会针对平时要查询的几个字段,建立一个联合索引

后面在java系统里写的SQL,都必须符合最左前缀匹配原则,确保你所有的sql都可以使用上这个联合索引,通过索引来查询
最左前缀匹配原则:对于复合索引Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份但只能是最左侧部分
create index (shop_id,product_id,gmt_create)
一个索引包含个字段,
那么mysql的比较字段顺序,先比较第一个字段,然后第二个字段,然后第三个字段。

如果您知 道姓,电话簿将非常有用;
如果您知道姓和名,电话簿则更为有用,
但如果您只知道名不姓,电话簿将没有用处。

所以说创建复合索引时,应该仔细考虑列的顺序。

设计索引原则

  1. 尽量使用唯一索引。区分度越高,索引效率越高。例如,学生表中学号是具有唯一性的字段。为该字段建立唯一性索引可以很快的确定某个学生的信息。
  2. 对于经常需要查询的字段建立索引,数据量大的表进行建立索引
  3. 对于经常需要排序的字段建立索引,因为索引本身就是有序的
  4. 尽可能使用短索引,因为每个磁盘块大小固定为16K,使用短索引,则每块可以存储更多的索引数据
  5. 限制索引的数目,并及时清理不需要的索引,因为索引也要占用空间,索引越多,更新表速度越慢

索引覆盖,索引下推

猜你喜欢

转载自blog.csdn.net/chongbin007/article/details/114858890