zoukankan      html  css  js  c++  java
  • B/B+树 MySQL索引结构

    索引

    索引的简介

    简单来说,索引是一种数据结构 其目的在于提高查询效率 可以简单理解为“排好序的快速查找结构”

    一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在中磁盘上
    我们一般所说的索引,如果没有特殊说明的话,就是指B+树结构组织的索引。其中聚集索引,次要索引,覆盖索引,复合索引,前缀索引,唯一索引默认都是使用B+树索引。 一般java开发知道这些基本够用了

    索引的优势

    类似大学图书馆建数目索引,提高数据检索效率,降低数据库的io成本
    通过索引对数据进行排序,降低数据排序成本,降低了cpu的

    劣势

    索引实际上也是一张表,保存了主键和索引字段,并指向实体表的记录,所以索引列也要空间

    虽然索引大大提高了查询速度,但是会降低更新表的速度,如对表进行insert,update和delete。因为更新表时,mysql不仅要保存数据,还要保存一下索引文件每次添加了索引列的字段

    索引只是提高效率的一个因素,如果你的mysql有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。

    索引的使用

    单值索引
    唯一索引
    复合索引

    基本语法

    show index from TableName;(查看表的索引)
    eg:show index from city;
    create [unique] index indexname(索引名称) on TableName(字段名);
    eg:create index idx_city_name on city(cname);
    eg:create index idx_city_idnamepid on city(id,name,pid);
    drop index indexname on TableName;
    eg:drop index idx_city_name on city;

    使用ALERT命令
    ALERT TABLE tbl_name ADD PRIMARY KEY(column_list);该语句添加一个主键,这意味着索引值必须是唯一的,且不能为null;
    ALERT TABLE tbl_name ADD UNIQUE index_name(column_list);这条语句创建索引的值必须是唯一的(除了null外,null可能会出现多次)
    ALERT TABLE tbl_name ADD INDEX index_name(colmun_list);添加普通索引,索引值可出现多次
    ALERT TABLE tbl_name ADD FULLTEXT index_name(column_list);该语句指定了索引为FULLTEXt,用于全文索引

    mysql索引结构

    BTree索引
    Hash索引
    full-text索引
    R-Tree索引

    检索原理

    哪些情况下需要创建索引

    a.主键自动建立唯一索引
    b.频繁作为查询条件的字段应该创建索引
    c.查询中与其它表关联的字段,外键关系建立索引
    d.频繁更新的字段不适合建立索引(因为每次更新不仅仅是更新数据还要更新索引,加重io负担)
    e.where条件里用不到的字段不创建索引
    f.单键/组合索引的选择问题(在高并发下倾向创建组合索引)
    g.查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度
    h.查询中统计或分组的字段

    哪些情况下不需要创建索引

    a.表记录太少
    b.经常增删改查的表(读少写多)
    c.数据重复且分布平均的表字段,因此应该只为最经常查询和最经常排序的数据列建立索引,注意,如果某个数据列包含许多重复内容,为它建立索引就没有太大的实际效果

     

      B-树

    B-树,这里的 B 表示 balance( 平衡的意思),B-树是一种多路自平衡的搜索树 
    它类似普通的平衡二叉树,不同的一点是B-树允许每个节点有更多的子节点。下图是 B-树的简化图.

    B-树有如下特点:

    1. 所有键值分布在整颗树中;

    2. 任何一个关键字出现且只出现在一个结点中;

    3. 搜索有可能在非叶子结点结束;

    4. 在关键字全集内做一次查找,性能逼近二分查找;

    B+ 树

    B+树是B-树的变体,也是一种多路搜索树, 它与 B- 树的不同之处在于:

    1. 所有关键字存储在叶子节点出现,内部节点(非叶子节点并不存储真正的 data)

    2. 为所有叶子结点增加了一个链指针

    简化 B+树 如下图

    为什么使用B-/B+ Tree

    红黑树等数据结构也可以用来实现索引,但是文件系统及数据库系统普遍采用B-/+Tree作为索引结构。MySQL 是基于磁盘的数据库系统,索引往往以索引文件的形式存储的磁盘上,索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,索引的结构组织要尽量减少查找过程中磁盘I/O的存取次数。为什么使用B-/+Tree,还跟磁盘存取原理有关。

    局部性原理与磁盘预读

    由于磁盘的存取速度与内存之间鸿沟,为了提高效率,要尽量减少磁盘I/O.磁盘往往不是严格按需读取,而是每次都会预读,磁盘读取完需要的数据,会顺序向后读一定长度的数据放入内存。而这样做的理论依据是计算机科学中著名的局部性原理:

    当一个数据被用到时,其附近的数据也通常会马上被使用
    程序运行期间所需要的数据通常比较集中

    由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率.预读的长度一般为页(page)的整倍数。

    MySQL(默认使用InnoDB引擎),将记录按照页的方式进行管理,每页大小默认为16K(这个值可以修改).linux 默认页大小为4K

    B-/+Tree索引的性能分析

     

    实际实现B-Tree还需要使用如下技巧:
    每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个结点只需一次I/O。
    假设 B-Tree 的高度为 h,B-Tree中一次检索最多需要h-1次I/O(根节点常驻内存),渐进复杂度为O(h)=O(logdN)O(h)=O(logdN)。一般实际应用中,出度d是非常大的数字,通常超过100,因此h非常小(通常不超过3)。
    而红黑树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性,所以红黑树的I/O渐进复杂度也为O(h),效率明显比B-Tree差很多。

    为什么使用 B+树

    1. B+树更适合外部存储,由于内节点无 data 域,一个结点可以存储更多的内结点,每个节点能索引的范围更大更精确,也意味着 B+树单次磁盘IO的信息量大于B-树,I/O效率更高。

    2. Mysql是一种关系型数据库,区间访问是常见的一种情况,B+树叶节点增加的链指针,加强了区间访问性,可使用在范围区间查询等,而B-树每个节点 key 和 data 在一起,则无法区间查找。

    原文链接:https://segmentfault.com/a/1190000004690721

    不积跬步,无以至千里!
  • 相关阅读:
    程序员第一定律:关于技能与收入
    Android——全屏显示的两种方式
    Android与JavaScript方法相互调用
    IT职场人生:找谁占卜
    Linux 2.6.23开始使用CFS(complete fair schedule),线程Priority不再有效
    如何查看一份linux kernel source的版本?
    tar解包的时候如何exclude一些目录
    rsync通过SSH来同步两台机器上的内容
    ArchLinux下配置TPLink WN550G PCI网卡为无线AP
    配置Linux下的时间服务器,让一批机器和一台机器时间同步
  • 原文地址:https://www.cnblogs.com/f66666/p/9782920.html
Copyright © 2011-2022 走看看