首页
学习
活动
专区
圈层
工具
发布
    • 综合排序
    • 最热优先
    • 最新优先
    时间不限
  • 来自专栏InvQ的专栏

    mysql 索引原理

    文章目录 1、索引的本质 2、索引的分类 2.1、Hash 索引 2.2、二叉树 2.4、B树(二三树) 2.5、B+树 3、主键目录 4、索引5索引页的分层 6、非主键索引 7.回表 1、索引的本质 索引的本质是一种排好序的数据结构。 2、索引的分类 在数据库中,索引是分很多种类的(千万不要狭隘的认为索引只有 B+ 树,那是因为我们平时使用的基本都是 MySQL)。而不同的种类很显然是为了应付不同的场合,那索引到底有那些种类呢? 2.1、Hash 索引 Hash 索引是比较常见的一种索引,他的单条记录查询的效率很高,时间复杂度为1。 但是,Hash索引并不是最常用的数据库索引类型,尤其是我们常用的Mysql Innodb引擎就是不支持hash索引的。主要有以下原因: Hash索引适合精确查找,但是范围查找不适合

    45240编辑于 2023-03-11
  • 来自专栏源码之路

    「Mysql索引原理(四)」单列索引

    单列索引 独立的列 例如,select actor_id from actor where actor_id+1=5; 这个查询无法使用actor_id列的索引。 前缀索引索引选择性 ? 索引的选择性:不重复的索引值(也称为基数)和数据表的记录总数(#T)的比值,范围从1/T到1之间。 city,3))/count(*) as sel3, count(distinct left(city,4))/count(*) as sel4, count(distinct left(city,5) )/count(*) as sel5 from city_demo ? 应用场景 存储网站会话时,需要在一个很长的十六进制字符串上创建索引。此时如果采用长度为8的前缀索引通常能显著地提升性能,且对上层应用完全透明。 后缀索引 字符串反转后做前缀索引

    1.1K20发布于 2020-09-04
  • 来自专栏爱明依

    MySQL 索引原理

    MySQL 索引原理 现在互联网应用中对数据库的使用多数都是读较多,比例可以达到 10:1。 并且数据库在做查询时 IO 消耗较大, 所以如果能把一次查询的 IO 次数控制在常量级那对数据库的性能提升将是非常明显的,因此基于 B+ Tree 的索引结构出现了。 这也就是为什么索引字段要尽可能小的原因。 索引使用的一些原则。

    52140编辑于 2022-04-01
  • 来自专栏源码之路

    「Mysql索引原理(七)」覆盖索引

    通常大家都会根据查询的WHERE条件来创建合适的索引,不过这只是索引优化的一个方面。设计优秀的索引应该考虑到整个查询,而不单单是WHERE条件部分。 如果一个索引覆盖所有需要查询的字段的值,我们就称之为“覆盖索引”。 覆盖索引是非常有用的工具,能够极大地提高性能: 索引条目通常远小于数据行大小,所以如果只需要读取索引,那MySQL就会极大地减少数据访问量。 在所有这些场景中,在索引中满足查询的成本一般比查询行要小得多。 不是所有类型的索引都可以成为覆盖索引。 覆盖索引必须要存储索引列的值,而哈希索引、空间索引和全文索引都不存储索引列的值,所以MySQL只能使用B+Tree索引所覆盖索引

    2.5K12发布于 2020-09-04
  • 来自专栏编程之禅

    MySQL索引原理

    MySQL索引原理 MySQL 的索引 概述 索引是数据库中一个排序的数据结构,用来协助快速查询和更新数据库表中的数据;数据是以文件的形式存放在磁盘上的,每一行数据都有它的磁盘地址;当没有索引时,比如从 Binary Search Trees**)是指左右子树的深度差绝对值不能超过 **1**;比如左子树的深度是 **2**,右子树的深度只能是 **1 | 3**;在这时按照顺序插入 **1、2、3、4、5、 同样,再以 **7、6、5** 的顺序插入就会变成左左形,就会发生右旋操作,把 **6** 提上去。所以为了保持平衡,**AVL** 树在插入和更新数据时执行了一系列的计算和调整操作。 在删除时会有相反的合并操作,然后再继续看 **4、5** 的分裂与合并操作。 INTO `employees` ( `emp_no`, `birth_date`, `first_name`, `last_name`, `gender`, `hire_date` ) VALUES ( 5,

    71630发布于 2021-07-14
  • 来自专栏源码之路

    「Mysql索引原理(三)」Mysql中的Hash索引原理

    索引只存储哈希码及行指针,所以索引的数据结构非常的紧凑,这也让哈希索引查找速度非常快,但是哈希索引也有他的限制。 不过访问内存中的行速度非常快(因为是MEMORY引擎),所以对性能影响并不大 哈希索引数据并不是按照索引值顺序存储的,所以无法用于排序 哈希索引不支持部分索引列查找,因为哈希索引始终是使用索引列的全部内容来计算哈希码 2、mysql同时提供了SHA1()、MD5()两个加密函数,不要使用这两个函数做哈希函数,他们是强加密函数,设计目标是最大限度消除冲突,但计算的哈希值很长,浪费空间且有时更慢。 select SHA1('CONGZHIZHI') select MD5('CONGZHIZHI') 空间数据索引 MyISAM存储引擎支持空间索引,可以用作地理数据存储。 全文索引 全文索引是一种特殊类型的索引,它查找的是文本中的关键字,而不是直接比较索引中值。全文索引和其他类索引的匹配方式完全不一样。

    10.2K11发布于 2020-09-04
  • 来自专栏源码之路

    「Mysql索引原理(六)」聚簇索引

    聚簇索引不是一种单独的数据类型,而是一种数据存储方式。 InnoDB的聚簇索引实际上在同一结构中保存了B+Tree索引和数据,当表有聚簇索引时,它的数据行实际上存放在索引的叶子节点中。 因为无法同时把数据行放在两个不同的地方,所以一个表只能有一个聚簇索引(覆盖索引可模拟多个聚簇索引的情况,后面会介绍) 因为是存储引擎负责实现索引,因此不是所有的存储引擎都支持聚簇索引。 本节课主要关注InnoDB,但是这里讨论的原理对于任何支持聚簇索引的存储引擎都是适用的。 聚簇索引中的记录是如何存放的? ? 叶子节点包含了全部数据,其他节点只包含索引列。 聚簇索引索引和数据保存在同一个B+Tree中,因此从聚簇索引中获取数据通常比在非聚簇索引中查找要快。 使用覆盖索引扫描的查询可以直接使用页节点中的主键值。 二级索引访问需要两次索引查找,而不是一次。因为聚簇索引一张表就有一个,二级索引叶子节点保存着主键列,查询时首先根据索引找到对应的主键列,然后根据主键列到聚簇索引中查找数据。 ?

    4K40发布于 2020-09-04
  • 来自专栏源码之路

    「Mysql索引原理(九)」前缀压缩索引

    MyISAM使用前缀压缩来减少索引的大小,从而可以让更多的索引可以放入内存中,这在某些情况下能极大地提高性能。默认只压缩字符串,但通过参数设置也可以对整数做压缩。 MyISAM压缩每个索引块的方法是,完全保存索引块中的第一个值。然后将其他值和第一个值进行比较得到相同前缀的字节数和剩余的不同后缀部分,把这部分存储起来即可。 所有在块中查找某一行的操作平均都需要扫描半个索引快。 对于CPU密集型应用,因为扫描需要随机查找,压缩索引使得MyISAM在索引查找上要慢好几倍。压缩索引的倒序扫描就更慢了。 压缩索引需要在CPU内存资源与磁盘之间做平衡。压缩索引可能只需要十分之一大小的磁盘空间,如果是I/O密集型应用,对某些查询带来的好处会比成本多很多。 可以在create table语句中指定pack_keys参数来控制索引压缩的方式。

    1.4K30发布于 2020-09-04
  • 来自专栏源码之路

    「Mysql索引原理(五)」多列索引

    很多人对多列索引的理解都不够。一个常见的错误就是,为每个列创建独立的索引,或者按照错误的顺序创建多列索引。 这样一来最好的情况下也只能是“一星”索引,其性能比起真正最优的索引可能差几个数量级。有时如果无法设计一个“三星”索引,那么不如忽略掉where子句,集中精力优化索引列的顺序,或者创建一个全覆盖索引。 ,但实际上更多时候说明了表上的索引建得很糟糕: 到底什么时候创建多列索引? 当出现服务器对多个索引做相交操作时(通常有多个and操作),则意味着需要一个包含所有相关列的多列索引,而不是多个独立的单列索引。 在一个多列BTree索引中,索引列的顺序意味着索引首先按照最左列进行排序,其次是第二列,等等。

    5.5K20发布于 2020-09-04
  • 来自专栏源码之路

    「Mysql索引原理(十一)」索引和锁

    举例: set autocommit=0; begin; select id from people where id<5 and id<>1 for update; ? InnoDB会锁住第一行,这是因为Mysql为该查询选择的执行计划是索引范围扫描: explain select id from people where id<5 and id<>1 for update 换句话说,底层存储引擎的操作是“从索引的开头开始获取满足条件id<5的记录”,服务器并没有告诉InnoDB可以过滤第一行的WHERE条件。 就像这个例子显示的,即使使用了索引,InnoDB也可能锁住一些不需要的数据。如果不能使用索引查找和锁定行的话问题可能会更糟糕,MySQL会做全表扫描并锁住所有的行,而不管是不是需要。 关于InnoDB、索引和锁有一些很少有人知道的细节:InnoDB在二级索引上使用共享锁。

    1.1K20发布于 2020-09-04
  • 来自专栏Java患者

    MySQL索引底层(二)--索引底层原理

    聚集索引 上次我们讲到了主键的索引,我们可以执行一下sql语句 explain select * from t_user where a = 1 我们可以看到这条sql走的是主键的索引,而在mysql的 InnoDB中,主键索引则是聚集索引,数据的物理顺序与键值的逻辑(索引)顺序相同,其实就是说主键索引跟其他列的数据是存在一起的。 t_user where b = 3 AND d = 1 我们可以看到当前走的索引是b字段,接着key_len的长度是5,那么5是怎么来的呢? 那么创建索引的本质又是什么呢,其实就是创建要给B+树的数据结构,跟我们前面所讲的主键索引是一样的, 创建主键索引,其实就是按主键排序,然后做一个B+树的数据结构,那么现在将字段b,c,e创建了索引,其实就是给 当我们执行上面的sql语句的时候,我们都知道这条sql不会走索引,从key_len字段中也可以看出,那么为什么没有走索引呢,因为我们创建索引的时候是指定了b,c,e三个字段创建了索引,现在我们执行这条sql

    83321发布于 2020-05-29
  • 来自专栏Java患者

    MySQL索引底层(一)索引底层原理

    MySQL索引底层原理 局部性与页 在操作系统中,我们执行一个指令去磁盘取数据,那么他会从磁盘取出4KB数据,这个4KB就是一个局部单位,而这4KB数据就是你的指令中取出的数据周围的数据,因为操作系统认为你下一次的数据会从这条数据的周围中取 那么在Mysql的操作当中,也有这么一个原理。 ? 页数据原理 ? 接下来的页就会变成上面的数据结构,假设我们现在要找a=6的数据,那么就会基于第一页去找,发现第一页没有,那就基于第一页到第二页去找,发现在页目录5中,那么a=6就在页目录为5的组中取出数据,假如当页数达到了

    1K31发布于 2020-05-29
  • 来自专栏MySQL 笔记

    索引的实现原理

    索引是什么? 定义: 索引是帮助MySQL高效获取数据的数据结构。 快速定位数据,并查询出来,这是索引干的事。 索引的文件存储形式与存储引擎有关, InnoDB 引擎的索引文件后缀是 .ibd ; MyISAM 引擎则是 .MYI 索引能快速定位数据,那它不是在内存中嘛?为啥保存在硬盘中呢? 索引存储在硬盘中,但是MySQL服务启动,它会将整个索引文件加载到内存中,这样就可以快速地找到某个key ( 数据 ),再根据数据结构去硬盘中读取对应的数据。 这里说下数据结构的实现原理 hash 把key转换为int 数据,取模运算,将key存储到hash表中,数据都会加载到内存中,数据表小,没啥问题,数据大,就会耗费大量内存空间,MySQL中采用的是“自适应 B+tree 索引的数据结构都有个小问题,如果索引的值是递增的,那么插入数据就会在新的叶子里插入,如果不是递增,就会将其中的页进行分列合并,旋转,因此索引的维护和更新比较麻烦。

    58620发布于 2020-05-29
  • 来自专栏一直在努力的Java菜鸡er

    MySQL索引原理探索

    MySQL索引原理探索 索引的本质其实就是各种各样的数据结构,在增删改查的各种操作有不通的时间复杂度和空间复杂度 索引的类型 Hash索引: 参考java中的hash结构,因为其结构,查找单条数据的效率特别高 4、B+ 树查询速度更稳定:B+ 所有关键字数据地址都存在叶子节点上,所以每次查找的次数 都相同所以查询速度要比B树更稳定; 5、B+ 树天然具备排序功能:B+ 树所有的叶子节点数据构成了一个有序链表, 正式因为如此,所以一个表最多只能有一个聚簇索引。 聚簇索引是 MySQL 基于主键索引结构创建的 非主键索引 对于非主键索引,MySQL也会帮忙维护一张B+树。你有多少索引,就会维护多少B+树。 插入的原理就是这样子的。此时每个数据页中的记录存放的实际是索引字段和主键字段,而其他字段是不存的(为什么不存放? 对于非主键索引(一般都是联合索引),在维护 B+ 树的时候,会根据联合索引的字段依次去判断,假设联合索引为:name + address + age,那么 MySQL 在维护该索引的 B+ 树的时候,首先会根据

    44030编辑于 2022-09-08
  • 来自专栏撸码那些事

    MySQL——索引实现原理

    在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的,本文主要讨论MyISAM和InnoDB两个存储引擎的索引实现方式。 答案是否定的,和一级索引(主键索引)没有什么区别。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。 MyISAM的索引方式索引和数据存放是分开的,非聚集”的,所以也叫做非聚集索引。 InnoDB索引实现 虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。 InnoDB的二级索引的叶子节点存储的不是行号(行指针),而是主键列。这种策略的缺点是二级索引需要两次索引查找,第一次在二级索引中查找主键,第二次在聚簇索引中通过主键查找需要的数据行。 数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次磁盘I/O就可以完全载入。

    1K21发布于 2018-08-20
  • 来自专栏MySQL 笔记

    索引的实现原理

    索引是什么? 定义: 索引是帮助MySQL高效获取数据的数据结构。 快速定位数据,并查询出来,这是索引干的事。 索引的文件存储形式与存储引擎有关, InnoDB 引擎的索引文件后缀是 .ibd ; MyISAM 引擎则是 .MYI 索引能快速定位数据,那它不是在内存中嘛?为啥保存在硬盘中呢? 索引存储在硬盘中,但是MySQL服务启动,它会将整个索引文件加载到内存中,这样就可以快速地找到某个key ( 数据 ),再根据数据结构去硬盘中读取对应的数据。 这里说下数据结构的实现原理 hash 把key转换为int 数据,取模运算,将key存储到hash表中,数据都会加载到内存中,数据表小,没啥问题,数据大,就会耗费大量内存空间,MySQL中采用的是 [B+tree] 索引的数据结构都有个小问题,如果索引的值是递增的,那么插入数据就会在新的叶子里插入,如果不是递增,就会将其中的页进行分列合并,旋转,因此索引的维护和更新比较麻烦。

    93520发布于 2020-05-26
  • 来自专栏源码之路

    「Mysql索引原理(十)」冗余和重复索引

    冗余索引 概念 冗余索引和重复索引有一些不同。如果创建了索引(A,B),再创建索引(A)就是冗余索引,因为这只是前一个索引的前缀索引。 另外,其他不同类型的索引(例如哈希索引)也不会是B树索引的冗余索引。 场景 冗余索引通常发生在为表添加新索引的时候。例如,有人可能会增加一个新的索引(A,B)而不是扩展已有的索引(A)。 在state_id列有个索引对下面的查询有用,假设查询名为Q1: select count(*) from userinfo where state_id=5; 一个简单的测试表明,该查询的执行速度是每秒 还有一个相关查询需要检索几个列的值,而不是只统计行数,假设名为Q2: select state_id ,city,address from userinfo where state_id=5; 如果有像WEHRE A=5 ORDER BY ID这样的查询,这个索引会很有作用。

    1.8K20发布于 2020-09-04
  • 来自专栏源码之路

    「Mysql索引原理(十六)」维护索引和表-更新索引统计信息

    MySQL的査询优化器会通过两个API来了解存储引擎的索引值的分布信息,以决定如何使用索引。 MyISAM将索引统计信息存储在磁盘中, ANALYZE TABLE需要进行一次全索引扫描来计算索引基数。在整个过程中需要锁表。 直到 My SQL5.5版本,InnoDB也不在磁盘存储索引统计信息,而是通过随机的索引访问进行评估并将其存储在内存中。 这里需要特别提及的是索引列的基数(Cardinality),其显示了存储引擎估算索引列有多少个不同的取值。 InnoDB引擎通过抽样的方式来计算统计信息,首先随机地读取少量的索引页面,然后以此为样本计算索引的统计信息。

    2.5K40发布于 2020-09-04
  • 来自专栏desperate633

    MySQL索引实现原理分析

    MyISAM 索引实现 MyISAM 引擎使用 B+Tree 作为索引结构,叶节点的 data 域存放的是数据记录 的地址。下图是 MyISAM 索引原理图: ? 辅助索引 在 MyISAM 中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只 是主索引要求 key 是唯一的,而辅助索引的 key 可以重复。 MyISAM 的索引方式也叫做“非聚集索引”,之所以这么称呼是为了与 InnoDB的聚集索引区分。 image.png 聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。 因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。

    97330发布于 2018-08-23
  • 来自专栏程序员奇点

    数据库索引原理

    先看个例子 在下面这个表T中,如果我执行 select* from t where k between3and5,需要执行几次树的搜索操作,会扫描多少行? DEFAULT '', index k(k))engine=InnoDB; insert into T values(100,1,'aa'),(208,2,'bb'),(300,3,'cc'),(509,5, image 现在,我们一起来看看这条SQL查询语句的执行流程: 在k索引树上找到k=3的记录,取得ID=300 再到ID索引树查到ID=300对应的R3 在k索引树取下一个值k=5,取得ID=500 再回到 可以看到,这个查询过程读了k索引树的3条记录(步骤1、3和5),回表了两次(步骤2和4)。 如何进行索引优化,避免回表? 什么是覆盖索引? 如果执行的语句是select ID from T where k between 3 and 5, 这时只需要查ID的值, 而ID的值已经在k索引树上了, 因此可以直接提供查询结果, 不需要回表。

    95830发布于 2020-05-29
领券