数据库索引

一. 什么是索引?

索引的目的就是便于快速查找。一本书的索引就是目录,可以让我们快速定位到要查找的内容;数据库的数据是以记录的方式存在的,所以索引的目的就是便于查找某一些记录。


索引类型(常见的数据库书籍中的关于索引类别的一些称呼):

  唯一索引:不允许其中任何两行具有相同值的索引

    使用主键和候选键建立的索引就是唯一索引,因为主键和候选键都可以确定唯一一个元组,即一张表中不存在相同的主键和候选键。在MySQL中,当你建立一个主键和候选键之后,MySQL会为它们分别建立索引。毕竟要想满足唯一性,依然会在更新数据的时候检验是否已经存在该主键或者候选键,而索引无疑是快速检验的标配。


  主键索引:可以认为是特殊的唯一索引,仅利用主键建立的索引


  单一索引:任何一个单一数据项建立的索引

    假如有下表【country,city,personNumber】,如果我们想查询某个国家的人数,我们就应当以国家建立索引,这样单一数据项建立的索引就是单一索引。

  复合索引:多个数据项建立的索引

    假如有下表【country,city,personNumber】,如果我们想查询某个城市的人数,我们就应当以【country,city】建立索引,多个数据项建立索引的时候,我们应当指定其排序的先后顺序,此处国家应优先排序,城市次之。


  聚簇索引:利用主键建立的索引,其物理存放顺序与主键顺序一致。因为数据只有一个物理存放顺序,所以一个表只有一个聚簇索引。

    在MySQL中,选定主键之后将会自动为主键创建索引。该索引可以维护主键的唯一性。非叶子节点包含了主键值,而叶子节点则指向了一条完整的记录


  非聚簇索引(二级索引,辅助索引):除了聚簇索引之外,其余所有的索引都是非聚簇索引

    非聚簇索引为什么是二级索引呢?重点在于一个二字。可以料想如果WHERE条件不是根据主键进行索引,那么我们就需要基于该非主键建立的索引进行检索,这样建立的索引叶子节点中包含了记录的主键,再使用主键在聚簇索引中找寻到完整的记录。可以说进行了两次B+ Tree查找而不是一次


  覆盖索引:一个索引包含(覆盖)所要查询的字段的值,注意覆盖索引与具体的查询有关

    假如有下表【country,city,personNumber】,如果我们想查询某个城市的人数,覆盖索引指的是可以将你想要查询的列建立在一个索引中,如(国家,城市,人数)作为一个复合索引,此时查找某一个国家的所有城市利用索引就可以完成,实际上这也相当于完成了聚簇索引的功能


二. 如何快速找到记录

说到查找算法,最朴实的就是无序排列的遍历了。在数据量较小的时候(PS:如果数据量较小我想数据库也不会有这么快的发展),此方法也不失为一种好的方法,毕竟没有相应数据结构的维护,插入更新数据的时候就可以再快一点。在学习算法的书籍中,数据结构总也是扮演着重要的角色。无序排列的数据简直就是一种佛系的数据结构,不管不顾它就是那样。一个好的算法基于一个合适的数据结构的例子比比皆是,堆排序基于堆这种数据结构;二叉搜索基于一棵构建好的二叉搜索树,哈希查找基于哈希表……所以数据库中为了快速查找到需要的记录也需要选择合适的数据结构。


三. 什么样的数据结构适合作为索引


下面就介绍几种数据库中快速查找记录的数据结构:


B+ Tree索引(MySQL,SQL Server,Oracle)


以上为一个3阶的B+ Tree,其上的数字我们可以认为使用ID建立起来的单一索引。如果需要使用如下SQL语句进行查询:


SELECT * FROM STUDENTS WHERE ID=1


   这个查询语句只需要三次查找就可以找到ID为1的叶子节点,找到存放该条记录(存放了ID为1的学生的所有属性)的物理地址,进而找到该条数据。


B+

Tree索引优点

  ①.全值匹配:指的是和索引中所有列进行匹配。假设以(姓,名,出生日期)三个数据项建立复合索引,那么可以查找姓名为张三,出生日期在2000-12-12的人

  ②.匹配最左前缀:假设以(姓,名,出生日期)三个数据项建立复合索引,可以查找所有姓张的人

  ③.匹配列前缀:假设有姓为司徒,司马的人,我们也可以查找第一列的前缀部分,如查找所有以司开头的姓的人

  ④.匹配范围值:可以查找所有在李和张之间的姓的人,注意范围查询只在复合索引的优先排序的第一列。(假设姓名按照拼音排序)

  ⑤.精确匹配前面列并范围匹配后一列:可以查找姓李并出生日期在2000-12-12之后的人或姓名为张三并出生日期在2000-12-12之后的人,注意范围第一个范围查询后面的列无法再使用索引查询

  ⑥.只访问索引的查询:即查询只需访问索引,而无需访问数据行。(此时应想到索引中的覆盖索引)


B+

Tree索引缺点

  ①.如果不是按照索引的最左列开始查找,则无法使用索引。如无法查找名为龙的人,也无法查找在2000-12-12之后出生的人,当然也无法查找姓中以龙结尾的人(注意为和含有的区别)

  ②.不能跳过索引中的列:无法查找姓李并在2000-12-12之后出生的人

  ③.如果查询中包括某个列的范围查询,则其右边所有列都无法使用索引优化查询


B Tree索引


哈希索引(MySQL,Oracle)


哈希索引优点

  ①.快速查询:参与索引的字段只要进行Hash运算之后就可以快速定位到该记录,时间复杂度约为1


哈希索引缺点

  ①.哈希索引只包含哈希值和行指针,所以不能用索引中的值来避免读取行

  ②.哈希索引数据并不是按照索引值顺序存储的,所以也就无法用于排序和范围查询

  ③.哈希索引也不支持部分索引列查询,因为哈希索引始终是使用索引列的全部数据进行哈希计算的。

  ④.哈希索引只支持等值比较查询,如=,IN(),<=>操作

  ⑤.如果哈希冲突较多,一些索引的维护操作的代价也会更高




参考资料

《高性能MySQL 第三版》Baron Schwartz / Peter Zaitsev / Vadim Tkachenko著

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

推荐阅读更多精彩内容

  • 对于数据库的优化主要包括三个部分:查询优化、索引优化和字段类型优化,其中,索引优化则是数据库优化的重中之重。一个查...
    charming_coder阅读 4,277评论 1 18
  • 索引对于数据库的性能是非常重要的,尤其是随着数据量越来越大。如果数据量比较少没有索引数据库性能可能表现也还不错,但...
    非典型_程序员阅读 454评论 0 1
  • 数据库索引是一个初级程序员容易忽视的东西,因为绝大多数时候我们都是使用简单的默认索引,也就是主键索引,但面对现在硬...
    onlyHalfSoul阅读 961评论 0 2
  • MySql数据库索引原理 写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点。考虑...
    琴匣自鸣阅读 1,681评论 0 2
  • 索引的基本原理,以及数据是如何被访问的 (一)SQLS如何访问没有建立索引的数据表 Heap译成汉语叫做“堆”,其...
    安易学车阅读 3,437评论 0 8