Mysql创建高性能的索引(一)

一. 索引是什么?

索引(key or “键”)是储存引擎用于快速找到记录的一种数据结构。这是索引的基本的功能,除此之外索引还有一些其他的属性。
举一个简单的例子:一本书里面有若干页,一页对应一个页码。如果想寻找这本书里关于作者信息的一些内容,如果没有索引的帮助,那么只能从页码为1的页,一行一行的去检索是不是你想看到的有关作者信息的内容,一直到最后一页的最后一行,这就是常说的全表扫描。但是如果我们使用了索引,那么我们如果想去找到作者信息相关的内容的话,只需要先去查询索引,由索引指向的页码跳转到相应的地方,这样大大提高了查询的效率。数据库里的索引也一样。(当然这取决于数据量的大小,如果是一个数据很小的表,那么可能使用索引的查询效率还不如全表查询来的快。在mysql里我们不需要担心这样的问题,mysql的查询优化器会在执行查询时先计算各种查询方式的代价,会自动的选择代价最低的方式进行查询)

二. 如果使用了orm,是否需要关心索引?

需要。orm是对象关系映射工具,是一个可以生产符合逻辑,合法的查询(大多数时候),但是索引的高性能的实现是复杂且方方面面受影响的。区区orm很难兼顾到各个方面。

三. 索引的类型

mysql里,索引的实现是在储存引擎层,而不是服务层。所以不同的储存引擎即使索引类型相同,具体实现也不完全相同。

1. B Tree

b树索引的结构

储存引擎以不同的方式使用b tree索引,性能不同各有优劣。

1.Myisam: 前缀压缩技术,使得索引更小,通过数据的物理地址引用到被索引的行。
2.Innodb: 使用原格式数据进行存储,通过主键引用到被索引的行。

但是特别的指出Myisam是只支持表锁的,用在不需要高并发的场景上使用。
b tree一般意味着数据都是顺序存储的。所以适合查找范围数据。索引对多个值进行排序的依据是create table 语句中定义索引时序的顺序。
b tree之所以可以增加查找速度是因为,储存引擎不需要在进行全表扫描来获取需要的数据,取而代之的是从索引的根结点向下直到找到对应的叶子结点,要么记录不存在。
b tree的高度与数据量的大小息息相关。
键前缀查找只适用于最左前缀的查找

索引匹配对下面的查询有效

1.全值匹配

索引中的所有列进行匹配。

2.匹配最左原则

index(a,b,c) 只能匹配到 a,b,c | a,b | a。

3.匹配列前缀

只匹配列前缀,比如 1以J开头的a字段。like "J%" 但是"%K"不能匹配到索引。

4.匹配范围值

比如name为allen和name为barrymore之间的人。

5.精准匹配某一列并范围匹配另外一列

name="alex" and address like "J%"

索引覆盖

通常可以支持只通过访问的索引的查询,即查询只需要访问索引,而不需要通过数据行。通过联合索引的形式实现。
了解了上面的信息我们知道了:索引的顺序十分重要

2.哈希索引

基于哈希表实现,储存引擎会对所有的索引列计算一个哈希码,不同键值计算出来的哈希码不一样。哈希吗储存在索引中勇士哈希表中保存指向每个数据行的指针。
只有Memory引擎显式支持哈希引擎,Memory引擎支持的是非唯一的索引。如果多个列的哈希值相同,那么索引会链表的形式存放多个记录到哈希条目中。因为索引自身只需要储存对应的哈希值,所以索引的结构十分紧凑。因为基于哈希表,所以对等值查询的速度十分的快。
但是哈希索引的缺点也十分明显:无法排序,不支持部分索引匹配查找(始终是全部的索引列的值通过计算得出去匹配的),只支持等值查询,如果有数量不少的键重复或者数据量大而造成的哈希冲突,会直接影响到数据库处理数据的能力。

innodb中的自适应哈希索引

innodb在使用时如果发现某些索引被使用的频繁时,他会在内存中基于b-tree索引之上再创建一个哈希索引,这样可以实现哈希索引的快速查找。这是一个内部的自动的无法控制的行为。不过如果有必要可以关闭这个功能。

在不同的储存引擎中实现隐式哈希索引(创建自定义哈希索引)

如果当前使用的储存引擎不支持哈希索引但是又想使用哈希索引,那么就可以模拟innodb的自适应哈希索引来创建一个。这样就可以享受到哈希索引的便利了。

实现思路:

在b树的基础上创建一个伪哈希索引,这跟真正的哈希索引不是一回事,还是使用b树进行查找,只是他使用的哈希值而不是键本身进行索引查找,只需要在where语句手动指定哈希函数即可。
举个例子:需要存储大量url,并且要求根据url查询对应的列,如果使用b树对url列进行索引那么这个内容就会很大,因为url本身是非常长的。正常情况下是这样进行查询

select id from url where url="http://www.baidu.com"

这时候我们可以通过实现一个自定义的哈希索引来优化这部分查询,删除原来的索引列,新增一个url_crc的列并增加它的索引,使用crc32函数做哈希,就可以通过下面的查询方式进行查询了

select id from url where url="http://www.baidu.com" and url_crc=CRC32("http://www.baidu.com")

这样做的性能相比上面的查询方式性能是非常高的,查询优化器会自动选择这个性能性很高的基于url_crc的索引列来完成查找,即使发生哈希冲突这样的查询也是非常效率的。
查询根据哈希值做快速的整数比较就能找到被索引的条目,再根据url列指定的信息就可以快速筛选出来,相比与完整的字符串筛选快了非常的多。
这样做的缺点就是需要维护哈希值,需要使用触发器,也可以通过手动维护。

3.空间数据索引(R树)

Myisam支持空间数据索引,可以存储地理数据,但是PostgreSql会做的更好。

4.全文索引

它是一种特殊类型的索引,它查找的是文本中的关键词,而不是直接的比较索引中的值。全文索引更类似于搜索引擎做的事情,而不是简单的where匹配。关于全文索引我们会单独来讲。

5.聚集索引 辅助索引

聚集索引/主键索引/聚簇索引 叶子节点里存放的是行记录。
如果定义了主键,那么主键就是聚集索引。
如果没有主键,那么第一个非空唯一的列就为聚集索引
如果都没有那么innodb会自动创建一个隐藏列row_id为聚集索引。

辅助索引/二级索引/普通索引叶子结点存放的是键值。需要回表查询才能拿到行数据。辅助索引比聚集索引更慢,可以考虑创建联合索引来达到索引覆盖的效果,去掉回表查询的操作,直接在索引列中拿到数据。

四.索引的优点

1.索引大大减少了需要扫描的数据量。
2.索引可以帮助避免创建临时表和排序。
3.索引可以将随机i/o变为顺序i/o。

五.索引的缺点

1.更新表也要更新索引文件。
2.索引文件占用储存空间。

~Tip:
1.很多重复的内容没必要使用索引。
2.非常小的表没必要使用索引。

六. 如何调试索引

使用mysql 的explain进行查询sql的执行计划。

这篇文章我们了解了索引的基本相关知识,接下来我们会讲到如何实现高性能的索引。

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