浅谈MySQL的索引(1)

      索引,不光是我们再工作中时常用到的一个名词,在面试的时候也是逢考必面的知识点,索引可以让我们的速度提升千百倍效率,也可以让我们本来运行很ok的sql变的不那么“和谐”,接下来我们就聊聊索引。


一、什么是索引


    MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。

我们可以简单理解为:快速查找排好序的一种数据结构。

或者理解为一本书的目录,个人认为重点是“有序”。


  • 索引的本质就是数据库中字段值的复制,该字段称为索引的关键字;

  • 索引也是一张表,记录保存了主键与索引字段,并指向了实际表数据;

  • 索引往往通过复杂的数据结构(双向链表、hash、BTree/B+Tree、)实现;


  • MyISAM存储引擎的表支持主索引,InnoDB存储引擎的表支持聚簇索引(主索引)与非聚簇索引(辅助索引)索引优化使用。


    二、主流索引查找算法


  • 线性查找,是一个链表,要搜索的话,需要从第一个往后一个个找

  • 二分查找,是线性查找的升级,也就是说二分查找是可以用线性查找的数据接口,但是算法不一样

  • 二叉树查找,进一步提高性能,引入了二叉树

  • 平衡二叉树,二叉树因为有平衡的问题,又进一步出现了平衡二叉树

  • B树,在平衡二叉树之后又发现了一个问题,之前的数据结构每一个节点都是一个行数据,这样的话对于磁盘的利用率是有问题的,因为我的数据要最终落到磁盘上,以一个节点为单位去读取磁盘效率是很低的

  • B+树,B树效率也有问题,出现了B+树,可以理解B+树是B树和线性的结合


  • 二、索引 的分类

  • 从索引存储结构划分:B Tree索引、Hash索引、FULLTEXT全文索引以及R Tree索引

  • 从应用层次划分:普通索引、唯一索引、主键索引、复合索引

  • 从键值划分:主键、辅助

  • 从数据存储以及索引逻辑关系划分:聚集索引、非聚集索引

  • 而Mysql索引主要有两种结构:B+Tree索引和Hash索引。我们平常所说的索引,如果没有特别指明,一般都是指B树结构组织的索引(B+Tree索引)。


    接下来我们就一一介绍一下各个索引名词:


    2.1、BTree 索引

            BTree  全称 Balanced Tree,是一种很普遍的数据库索引结构,oracle默认的索引类型。

            其特点是定位高效、利用率高、自我平衡,特别适用于高基数字段,定位单条或小范围数据非常高效。理论上,使用Btree在亿条数据与100条数据中定位记录的花销相同。


    演算如下:
    读取root节点,判断82大于在0-120之间,走左边分支。
    读取左边branch节点,判断82大于80且小于等于120,走右边分支。
    读取右边leaf节点,在该节点中找到数据82及对应的rowid
    使用rowid去物理表中读取记录数据块(如果是count或者只select rowid,则最后一次读取不需要)


        而由于Btree索引对结构的利用率很高,定位高效。当1千万条数据时,Btree索引也是三层结构(依稀记得亿级数据才是3层与4层的分水岭)。定位记录仍只需要三次I/O,这便是开头所说的,100条数据和1千万条数据的定位,在btree索引中的花销是一样的。


    Btree索引的自我平衡(平衡扩张)借用下面几张图进行说明:


         新建一个索引,索引上只会有一个leaf节点,取名为Node A,不断的向这个leaf节点中插入数据后,直到这个节点满;


          当Node A满之后,我们再向表中插入一条记录,此时索引就需要做拆分处理:会新分配两个数据块NodeB & C,如果新插入的值,大于当前最大值,则将Node A中的值全部插入Node B中,将新插入的值放到Node C中;否则按照5-5比例,将已有数据分别插入到NodeB与C中;


    无论采用哪种分割方式,之前的leaf节点A,将变成一个root节点,保存两个范围条目,指向B与C,结构如下图:


    当Node C满之后,此时 Node A仍有空余空间存放条目,所以不需要再拆分,而只是新分配一个数据块Node D,将在Node A中创建指定到Node D的条目:


    如果当根节点Node A也满了,则需要进一步拆分:新建Node E&F&G,将Node A中范围条目拆分到E&F两个节点中,并建立E&F到BCD节点的关联,向Node G插入索引值。此时E&F为branch节点,G为leaf节点,A为Root节点:


    在整个扩张过程中,Btree自身总能保持平衡,Leaf节点的深度能一直保持一致。

    参考文章:http://zsuil.com/?p=1184


    2.2、B+Tree索引

    MySQL数据库索引采用的是B+Tree结构,在B-Tree结构上做了优化改造,其特点:

  • 只有叶子节点包含索引和数据

  • 非叶子节点只存储索引值

  • 叶子节点用指针连接,提高区间访问性能

  • 对比B树来说,B+树范围查找时,只需要定位俩个节点的索引值,然后利用叶子节点指针进行遍历即可,而B树需要遍历范围内所有的节点数据,俩相对比,B+树效率更高




  • 2.3、Hash 索引

        Hash索引是基于Hash表实现,只有查询条件精确匹配Hash索引中的所有列时,才能够使用到Hash索引。也就是说,Hash索引只能用在等值查询,那么范围和模糊查询就不可以了;存储结构如下图:


        对于Hash索引中的所有列,存储引擎都会为每一行计算一个Hash码,Hash索引中储存的就是Hash码。

        Hash索引表中保存每一个Hash索引所代表的数据行的指针,由于Hash索引本身只存储Hash码,所以Hash索引结构比较紧凑,那么查询速度比较快。


    2.2、FULLTEXT全文索引

    全文索引,通过建立倒排索引,可以极大的提升检索效率,解决判断字段是否包含的问题. 


    例如: 有title字段,需要查询所有包含 "政府"的记录. 需要 like "%政府%"方式查询,查询速度慢,当查询包含"政府" OR "中国"的需要是,sql难以简单满足.全文索引就可以实现这个功能.


    旧版的MySQL的全文索引只能用在MyISAM表格的char、varchar和text的字段上。 

    不过新版的MySQL5.6.24上InnoDB引擎也加入了全文索引,所以具体信息要随时关注官网,

    -- 方式1、创建表的同时创建全文索引CREATE TABLE article (    id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,    title VARCHAR(200),         body TEXT,         FULLTEXT(title, body) ) TYPE=MYISAM; -- 方式2.通过 alter table 的方式来添加ALTER TABLE `student` ADD FULLTEXT INDEX ft_stu_name  (`name`) ;  -- ft_stu_name是索引名,可以随便起  -- 或者:ALTER TABLE `student` ADD FULLTEXT ft_stu_name  (`name`);-- 方式3. 直接通过create index的方式CREATE FULLTEXT INDEX ft_email_name ON `student` (`name`);  -- 也可以在创建索引的时候指定索引的长度:CREATE FULLTEXT INDEX ft_email_name ON `student` (`name`(20));

    使用全文索引

     使用全文索引的格式:  MATCH (columnName) AGAINST ('string'); eg:         SELECT * FROM `student` WHERE MATCH(`name`) AGAINST('聪');        当查询多列数据时:         建议在此多列数据上创建一个联合的全文索引,否则使用不了索引的。       SELECT * FROM `student` WHERE MATCH(`name`,`address`) AGAINST('聪 广东');


    不知不觉写到这已经2k多字了,本期我们就写到这里,下期我们继续

    探讨索引。
    …………………………………分割线……………………………

    不积跬步,无以至千里;不积小流,无以成江海。

    我都墨迹这么半天了 ,你不点关注,不点赞,不收藏,还不转发,你想干啥!!!!

    关注我,每天分享一些小知识点。分享自己的小心得,包含但不限于初、中、高级面试题呦!!!

    最后编辑于
    ©著作权归作者所有,转载或内容合作请联系作者
    • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
      沈念sama阅读 203,456评论 5 477
    • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
      沈念sama阅读 85,370评论 2 381
    • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
      开封第一讲书人阅读 150,337评论 0 337
    • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
      开封第一讲书人阅读 54,583评论 1 273
    • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
      茶点故事阅读 63,596评论 5 365
    • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
      开封第一讲书人阅读 48,572评论 1 281
    • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
      沈念sama阅读 37,936评论 3 395
    • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
      开封第一讲书人阅读 36,595评论 0 258
    • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
      沈念sama阅读 40,850评论 1 297
    • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
      茶点故事阅读 35,601评论 2 321
    • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
      茶点故事阅读 37,685评论 1 329
    • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
      沈念sama阅读 33,371评论 4 318
    • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
      茶点故事阅读 38,951评论 3 307
    • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
      开封第一讲书人阅读 29,934评论 0 19
    • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
      开封第一讲书人阅读 31,167评论 1 259
    • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
      沈念sama阅读 43,636评论 2 349
    • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
      茶点故事阅读 42,411评论 2 342

    推荐阅读更多精彩内容

    • 个人专题目录[https://www.jianshu.com/p/140e2a59db2c] 1. 性能下降SQL...
      Java及SpringBoot阅读 1,279评论 0 4
    • 索引的分类 从存储结构上来划分: BTree索引(B-Tree或B+Tree索引),Hash索引,full-ind...
      double_hi阅读 303评论 0 0
    • 先来看个问题 假设现在有100000条从0到10000且从大到小排列的整型数据,1条数据的大小假设(真的只是假设)...
      kindol阅读 526评论 0 2
    • 说到索引,很多人都知道“索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址,在数据...
      爱情小傻蛋阅读 675评论 2 2
    • 一、MySQL中索引的语法 创建索引 在创建表的时候添加索引 在创建表以后添加索引 注意: 索引需要占用磁盘空间,...
      _大叔_阅读 202评论 0 1