从磁盘I/O角度聊聊Mysql索引

从磁盘I/O角度聊聊Mysql索引

首先思考下这个问题,为什么添加了索引就能提高mysql的查询效率呢?MySQL查询中,性能瓶颈究竟在哪里?也就是今天所说的:磁盘I/O上

为什么添加了索引就能提高查询效率呢?

不同与Redis、Memcached等内存储存数据库,MySQL数据是以存储引擎规定的特定数据格式存储在物理磁盘上的。计算机存储体系如下图:

image-20200426205957608.png

所以,mysql查询中,最耗时的阶段就是磁盘I/O阶段,那如何减少mysql查询中磁盘的I/O次数呢?

假设有一张表,里面储存了N条数据,查询其中符合条件的数据,时间复杂度为O(N),需要对整个表进行顺序遍历。那么添加了索引为什么就能提交查询的效率呢,我们可以先看看索引的数据结构,mysql最主要的索引数据结构采用了BTree也就是B+树。我们定义一张数据表,其中id为主键索引,age是一个索引字段

image-20200426210513462.png

,然后往数据表中加入如下数据:

image-20200426210625973.png

与之对应age建立的B+树结构如下:

这是一个平衡有序N叉树(相对于平衡二叉树而言,B+树的非叶子节点可以有N个分支,相对于B树来说,B+树的非叶子节点是不存储实际数据,仅用于B+树的检索,叶子节点则用于存储真正的数据)第一层为非叶子节点,只存储了age信息,二层为叶子节点,存储了age信息和主键id的信息。

B+树的优势:非叶子节点不存储真正的数据,可以保证存储更多的检索分叉,可以降低整棵树的高度,从而降低磁盘I/O,叶子结点之间是相互连接的,构成有序的双向链表,方便叶子结点双向的横向遍历,有利于数据的范围查找

image-20200426210727484.png

在进行此条sql查询的时候,mysql会用age字段的索引进行查找,从根节点开始,然后按照B+树的结构一层一层的往下遍历,找到符合条件的数据后会根据索引上对应的主键id再去主键索引上查找具体的数据,如下图

image-20200426211702014.png

整个过程的时间复杂度为O(logN),从而达到提高查询效率的目的,当然使用了索引也不是就万事大吉,关机开黑,在索引上仍有功夫可下

如何正确用到索引

从减少磁盘I/O的角度上优化索引

  1. InnoDB索引,主键尽量避免使用很长的字段

和 myisam储存引擎不同,myisam索引文件和数据文件是分开存储的,myisam索引上叶子结点数据记录的指向是物理地址,根据物理地址去数据文件查找对应的数据,如图

image-20200426212856534.png

,而InnoDB叶子结点上存储的是索引值和数据记录的指向(主键),如果主键字段过长,二级节点存储的主键就会越少,会使整个二级节点索引数更大,检索会需要更多的I/O次数

image-20200426212958889.png
  1. 在保障索引区分度的情况下,被索引的字段尽量不要太长

    在 MySQL 的InnoDB储存引擎中,BTree索引的每个节点都是一个磁盘页面,称为page,大小一般默认16k

  show variables like 'innodb_page_size';

在BTree的检索中,每读取一个节点就会进行一次磁盘I/O,一次磁盘I/O就获得更多的索引建,整个B+树就会降低

索引的区分度(选择性):不重复的索引值(基数)/ 索引总数,这个值会在(0,1]之间,越趋近1则表示这个索引区分度越高越有价值

    select count(distince(name)) / count(1) as selectivity from t_student;

假设使用了更短的索引建

    select count(distince(left(name,1))) / count(1) as selectivity from t_student;
  1. 查询中可以利用索引覆盖,从而避免不必要的回表

    回表:通过二级索引无法查到整条数据的记录,需要根据二级索引查找主键再根据主键索引去查找整条数据的过程

    如果查询所需要的的信息恰巧在二级索引中能够得到,那就可以避免不必要的回表,减少磁盘的I/O次数,不需要回表的现象称为 索引覆盖 。进而引申除了联合索引,从而达到索引覆盖的目的

  2. 不要建立太多的索引

    数据表中的任何一条数据的写操作都会影响到索引树,随着数据量的增大,索引树也会变得越来越大,数据的写操作会耗费更多的磁盘I/O次数,在索引区分度非常低的字段上建立索引,反而达不到提升查询效率的目的

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

推荐阅读更多精彩内容