关于mysql索引二三事

什么是索引?

索引的本质是独立于数据本身之外的一种数据结构,它是基于某个或某些字段建立一堆有序可快速高效查找的数据,类似字典中首字母索引,或图书馆中图书的索引;

索引存在核心是为了过滤数据+检索,同时能快速定位数据的实际物理位置。其根本作用是要减少查询时的逻辑和物理IO或CPU运算,索引在运行中很多时候会加载到缓存中,通过索引定位数据在磁盘上的物理地址,进行数据获取。

在mysql上索引最常用的数据结构就是B+树,类似平衡二叉树的平衡多叉树,它的叶子节点会指向数据相关物理地址,从而实现快速定位数据;其树的高度就决定了定位数据位置需要IO次数,假设总的数据量为N,树的每个节点的数据量为m,这树高度就为log(m+1)N,所以通过索引只需要log(m+1)N次IO加上计算就可以定位到数据,这对比整个数据表遍历会是一个极大的提升(完全不在一个数量级上)。

B+树结构图


具体索引的原理,推荐看一下美团点评团队的一篇文章:索引原理和慢查询优化



维护索引需要的什么代价?

1. 索引需要占用额外储存空间,包含内存空间,也就意味着额外的IO操作

2. 数据表每一次更新,需同步调整相关的索引,额外的CPU和IO负载。

3. 当数据量增加到一定程度,索引本身的数据结构会特别庞大,维护起来成本会非常高

之前公司有做过数据迁移,千万级别的表,在有索引插入的情况下,执行了几个小时,但去掉索引,迁移完成后重建索引,不到1小时就完成


索引类型介绍

聚集索引和非聚集索引

在存储结构上不同可以将索引分为聚集索引和非聚集索引;一般来说,基于聚集索引的插入会特别快,碎片化数据也会少很多,单条查询也会快很多。

聚集索引

聚集索引单表上是唯一的,一个表最多只能有一个聚集索引。聚集索引在物理存储上有有序的,即代表数据行在磁盘的是按照聚集索引的顺序存储的。聚集索引的叶子节点是数据行,即在聚集索引的叶子节点上,直接可以找到数据本身。

非聚集索引

非聚集索引可以在单表存在多个逻辑上有序,物理上无序非聚集索引的叶子节点上存储的是索引块,里面对应的是相关数据的物理地址,并不是数据本身

类型划分

【普通索引】

【唯一索引】 值唯一,可以为null

【主键索引】 值唯一,不可为null,且每个表唯一

【组合索引】 多个字段的组合索引

【全文索引】 富文本,简易搜索引擎使用

数据结构划分

B+树

B-树

哈希索引



使用索引需要注意什么?(阅读划重点)

1. 频繁更新读少写多的表不适合过多索引

2. 最好的索引是能在平衡树叶子节点上快速定位到数据,过滤掉不在查询区间的数据,这就意味重复性低的字段更适合作为索引,比如自增键、时间戳、唯一字段等;不适合索引的字段比如少量状态、逻辑删除标记字段、性别等

3. 索引列切记不能有空值(null),请设置字段not null+默认值,null会影响索引效率

4. 数字字段比字符字段更适合索引,索引的核心在排序,数字的比较CPU运算量更少,需要的内存、逻辑IO和物理IO也更少,建立字段时如果可以尽量使用数字类型

5. 索引的建立和查询是基于字段的排序,如果字符字段过长,会出现极大增加排序负荷,并且会导致额外IO,使用索引字段请注意调整字段长度,不定长度或过长字段不适合索引,相反较短的字段就更适合;而一般数字字段都比字符字段短,占用空间也越少

6. 每个表最好都要有一个主键,使用主键在做表更新和删除会更加方便和安全,同时方便扩展、松耦合系统;在innodb引擎上,建议使用于业务无关的自增键来做主键,因为innodb会默认使用自增键来作为表的聚集索引(见索引类型章节),可以增加更新效率,减少数据碎片;自增主键还有特点是有时序,在业务逻辑上很多时候很有用。

7. 组合索引是指在业务查询逻辑,经常一起出现的字段组合成一个索引,会更加高效;列重复值较多的、单独索引效率低的字段也可考虑使用组合索引(比如一级分类和二级分类的组合索引);组合索引的建立要尽量对查询形成索引覆盖,其前置索引字段一定是使用要是最频繁的

8. 组合索引要注意最左前缀匹配原则,组合索引的原理是将多个字段按照提供的顺序组合后的整体作为索引排序;在mysql中,引擎会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,所以组合索引(a,b,c)可以匹配(a=1,b>1)的查询,但匹配不到(a=1,b>1,c=1),其中c=1会进行单独查询;(a=1,b=1)会用到索引,(b=1,c=1)会用不到。同样模糊查询中(a like 'xxx%')会用到a索引,但(a like '%xxxx')用不到;

9. 尽量的扩展索引,不要新建索引。根据实际业务情况,调整索引时,如无必要,不要新增索引,考虑扩展组合索引

10. 索引列请保持干净不要有任何计算,会导致索引无效;比如unix_timstamp()-[timefield] < 180,替换为[timefield]>unix_timstamp()-180

11. 反向查询会使索引无效,比如a<>1,not in查询,not in使用not exist替代

12. 使用组合索引字段是可以乱序的,查询引擎会根据索引来调整顺序。(a,b,c)组合索引,会匹配c>1 and a=2  and b=3的情况

13. 使用union替代or,在某些情况or查询会导致映射不到索引,比如select * from table where a=1 or b=2 替换为 select * from table where a=1 union select * from table where b=2,这样就可以使用a,b两个索引;同一字段的or查询使用in替代。在新版的mysql中(5.6?)查询引擎已可自动转化,但遇到复杂sql时,可能会转换失败

14. 如果查询用到多个索引的时,可以手动将过滤掉更多数据的索引字段放到前面,可以优化查询

15. 大表比如千万级别的表调整索引会很长时间锁表,尽量在一开始考虑好索引建立

16. 索引越多,维护成本也越高;不要过度索引,能在业务逻辑层做优化的,就不要放到数据库上来,特别是在高并发系统中,数据库一般都是瓶颈,请解放数据库。索引的使用的大的方向是:宜短不宜长,宜少不宜多

17. 技术的事没有绝对标准,可以考虑实际业务需求添加需要索引,但添加之前要考虑上面的事项。



原文  博客leesenlen.com - mysql索引二三事

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

推荐阅读更多精彩内容