索引是数据库系统里面最重要的概念之一。一句话简单来说,索引的出现其实是为了提高数据查询的效率,就像书的目录一样。

常见模型

索引的出现是为了提高查询效率,但是实现索引的方式却有很多种,这里就介绍三种常见、也比较简单的数据结构,它们分别是哈希表、有序数组和搜索树。

哈希表

哈希表是一种以key-value存储数据的结构。通过哈希函数把key换算成一个确定位置,然后把value放在这个数据的这个位置上。

但是当存储的数据越来越多,就有可能出现两个不同的key通过哈希函数得到了一样的值,这时候就出现冲突。而这时就引入链表来解决这种冲突了。

哈希表这种数据结构适用于只有等值查询的场景,时间复杂度为O(1),但是对于范围查找就必须全部遍历了,时间复杂度为O(n)。

有序数组

有序数组在等值查询和范围查询场景中的性能非常优秀。

但是需要往中间插入时就必须要挪动数据,时间复杂度很高。

搜索树

二叉搜索树在查询和插入、删除数据方面能够中和上面两种结构。查找时间复杂为O(logn)、插入删除的时间复杂度为O(logn)。

虽然二叉搜索树的搜索效率很高,但是在大多数的数据库并不使用二叉树。原因是索引要写在磁盘上。

磁盘上的随机读是很耗时间的,为了让一个查询尽量少地读磁盘,就必须在查询过程中访问尽量少的数据块。

那么就不应该使用二叉树,而是要使用“N”叉树,这里的“N”取决于数据块的大小。

B+树是为磁盘设计的一种平衡查找树。在B+树中,所有记录节点都是按键值的大小顺序存放在同一层的叶子节点上,由各叶子节点指针进行连接。

索引类型

B+树索引

数据库中的B+树索引可以分为主键索引和普通索引两种,也有叫聚集索引(clustered index)和辅助索引(secondary index)

但不管是主键索引还是普通索引,都是使用B+树的,即高度平衡的,叶子节点存放着所有数据。

主键索引

InnoDB存储引擎表是索引组织表,即表中数据按主键顺序存放。

主键索引就是按照每张表的主键构造一棵B+树,同时叶子节点中存放的是行数据。每张表只能拥有一个主键索引。

普通索引

普通索引与主键索引的区别在于,普通索引的叶子节点并不包含行数据,而是包含主键。

基于主键索引和普通索引的查询有什么区别?

  • 如果语句是select * from T where ID=500,即主键索引查询方式,则只需要搜索ID这棵B+树;
  • 如果语句是select * from T where k=5,即普通索引查询,则需要先搜索k索引树,得到ID的值为500,再到ID索引树搜索一次。这个过程称为回表。

也就是说,基于非主键索引的查询需要多扫描一棵索引树。因此我们应该尽量使用主键索引查询。

哈希索引

哈希索引基于哈希表实现,在MySQL中只有Memory引擎显示支持哈希索引,也是Memory引擎表的默认索引类型。

下面是创建Memory引擎表的语句:

CREATE TABLE `testhash` (
`fname` varchar(50) DEFAULT NULL,
`lname` varchar(50) DEFAULT NULL,
KEY `fname` (`fname`) USING HASH
) ENGINE=MEMORY;
哈希索引限制
  1. 哈希索引只保存哈希码和指针,而不存储字段值,所以不能使用索引中的值来避免读取行。不过访问内存中的行速度非常快,所以对性能影响并不大。
  2. 哈希索引数据并不是按照索引值顺序存储的,所以无法无法用于排序
  3. 哈希索引不支持部分索引列查找,因为哈希索引始终是使用索引列的全部内容来计算哈希码。
  4. 哈希索引只支持等值比较查询,不支持范围查询。
  5. 哈希冲突会影响查询速度,此时需要遍历索引中的行指针,逐行进行比较。
  6. 如果哈希冲突很多,一些索引维护操作的代价会很高。
自定义哈希索引

在InnoDB中,某些索引值被使用的非常频繁的时候,它会在内存中基于B+树的基础上再创建一个哈希索引,使其不必要从根节点就查找。完全自动的内部行为,用户无法配置或更改。

MySQL索引(一)索引基础的更多相关文章

  1. MySql基础笔记(二)Mysql语句优化---索引

    Mysql语句优化--索引 一.开始优化前的准备 一)explain语句 当MySql要执行一个查询语句的时候,它首先会对语句进行语法检查,然后生成一个QEP(Query Execution Plan ...

  2. 数据库基础知识详解五:MySQL中的索引和其两种引擎、主从复制以及关系型/非关系型数据库

    1.MySQL中的索引 在MySQL,索引是由B+树实现的,B+是一种与B树十分类似的数据结构. 形如下面这种: 其结构特点: (1)有n课子树的结点中含有n个关键码. (2)非根节点子节点数: ce ...

  3. MySQL的btree索引和hash索引的区别

    Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-T ...

  4. MySQL(五) MySQL中的索引详讲

    序言 之前写到MySQL对表的增删改查(查询最为重要)后,就感觉MySQL就差不多学完了,没有想继续学下去的心态了,原因可能是由于别人的影响,觉得对于MySQL来说,知道了一些复杂的查询,就够了,但是 ...

  5. Mysql数据库的索引原理

    写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将 ...

  6. MySQL优化四 索引优化

    索引为什么能提高数据访问性能? 很多人只知道索引能够提高数据库的性能,但并不是特别了解其原理,其实我们可以用一个生活中的示例来理解. 我们让一位不太懂计算机的朋友去图书馆确认一本叫做<MySQL ...

  7. 数据库 MySQL进阶之索引

    数据库的索引非常重要,基本面试数据库的问题都在索引上,所以这里小编整理出来,一方面为了自己复习,一方面也方便大家. 一,索引前传 在了解数据库索引之前,首先有必要了解一下数据库索引的数据结构基础,那么 ...

  8. 数据库索引使用数据结构及算法, 及MySQL不同引擎索引实现

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  9. MySQL 进阶之索引

    一,索引前传 在了解数据库索引之前,首先有必要了解一下数据库索引的数据结构基础,那么什么样的数据结构可以作为索引呢? B-tree是最常用的用于索引的数据结构.因为它们是时间复杂度低, 查找.删除.插 ...

  10. MySQL 聚簇索引&&二级索引&&辅助索引

    MySQL非聚簇索引&&二级索引&&辅助索引 mysql中每个表都有一个聚簇索引(clustered index ),除此之外的表上的每个非聚簇索引都是二级索引,又叫辅 ...

随机推荐

  1. 动态规划——用二进制表示集合的状态压缩DP

    动态规划当中有非常常见的一个分支--状态压缩动态规划,很多人对于状态压缩畏惧如虎,但其实并没有那么难,希望这文章能带你们学到这个经典的应用. 二进制表示状态 在讲解多重背包问题的时候,我们曾经讲过二进 ...

  2. c++11-17 模板核心知识(一)—— 函数模板

    1.1 定义函数模板 1.2 使用函数模板 1.3 两阶段翻译 Two-Phase Translation 1.3.1 模板的编译和链接问题 1.4 多模板参数 1.4.1 引入额外模板参数作为返回值 ...

  3. 【Kata Daily 190908】How Much?

    原题: I always thought that my old friend John was rather richer than he looked, but I never knew exac ...

  4. 矩阵连乘问题的算法复杂度的计算--卡塔兰数(Catalan数)的数学推导和近似公式

    author: cust-- ZKe --------------------- 这里以连乘积加括号问题为背景: 由于矩阵的乘积满足结合律,且矩阵乘积必须满足左边矩阵的列数的等于右边矩阵的行数,不同的 ...

  5. Python调用飞书发送消息

    一.创建飞书机器人 自定义飞书机器人操作步骤,具体详见飞书官方文档:<机器人 | 如何在群聊中使用机器人?>

  6. c#分割

    Hashtable h = new Hashtable(); ArrayList l = new ArrayList(); string[] lines = System.IO.File.ReadAl ...

  7. python数据分析 Numpy基础 数组和矢量计算

    NumPy(Numerical Python的简称)是Python数值计算最重要的基础包.大多数提供科学计算的包都是用NumPy的数组作为构建基础. NumPy的部分功能如下: ndarray,一个具 ...

  8. 自定义MFC对话窗口的类名

    默认情况下,MFC对话框的窗口类名为"#32770",如果想自定义窗口类名呢,需要两步: 1.修改rc文件 这一步需要直接编辑rc文件,使用任意记事本工具即可,找到窗口的相关定义, ...

  9. 我叫Mongo,干了「查询终结篇」,值得您拥有

    这是mongo第三篇"查终结篇",后续会连续更新5篇 mongodb的文章总结上会有一系列的文章,顺序是先学会怎么用,在学会怎么用好,戒急戒躁,循序渐进,跟着我一起来探索交流. 通 ...

  10. EFCore自己用的点东西

    测试一下EF core 的操作 蛀牙总是用导航属性有的时候有点不理解 写个例子给自己用 class Program { static void Main(string[] args) { MyDbCo ...