广告
返回顶部
首页 > 资讯 > 数据库 >如何理解并实现索引的原理和优化
  • 900
分享到

如何理解并实现索引的原理和优化

2024-04-02 19:04:59 900人浏览 独家记忆
摘要

这篇文章主要讲解了“如何理解并实现索引的原理和优化”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何理解并实现索引的原理和优化”吧!Part1为什么kafk

这篇文章主要讲解了“如何理解并实现索引的原理和优化”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何理解并实现索引的原理和优化”吧!

Part1为什么kafka不需要我们关心索引,而Mysql却需要?

Kafka 和 mysql 虽然最终数据都是落磁盘,但是两者在用途和数据查询方式上有着很大的差异,所以决定了数据的存储结构不同,进而决定了索引的复杂程度。

我们先看下kafka的存储结构:

如何理解并实现索引的原理和优化

由于 kafka 的定位是进行稳定的高性能数据读写。所以对磁盘来说,是采用顺序读写的方式,落在了一些 .log 文件中,并以基准偏移量补0命名。

为了实现高速查找 kafka 创建了稀疏索引文件(隔一段数据创建一条,而非全量),即index文件。其中维护消息的 offset 和 .log文件的物理位置。通过二分查找快速定位log文件并顺序扫描找到目标。

所以,kafka的索引组织方式是相对简单、方案相对固定,但Mysql却不行。Mysql是关系型数据库,是为了支持复杂的业务数据查询而创建的,查询方式、数据获取需求多种多样,要求MySQL具备更加复杂的索引机制来加速复杂业务查询场景。

Part2MySQL数据怎么被组织[1][2]

以InnoDB存储引擎来看mysql数据存储:

如何理解并实现索引的原理和优化

参考了三本资料,基本把最重要的部分都概括了

数据被分了多个逻辑层:行->页->区块->段->表空间。

我们知道,InnoDB存储引擎表是Index organized的(数据即索引,索引即数据),他们都维护在一个B+树上,数据段就是叶子节点,索引段就是非叶子节点;

而我们划分的段、区块 其实都是为了利用操作系统的资源(比如每次从磁盘加载到内存的数据大小按区块来约定等等`)来达到更高效读写的目的,逻辑划分的。

其中页是MySQL和磁盘交互的最小单位,怎么从页找到行,怎么聚合到块、到段再到空间呢。

1数据记录最小单位-- 行

从上面总图中摘出一条记录的结构如下图:

如何理解并实现索引的原理和优化

我们可以看到,记录头中除了行号,还有下一条记录的标识next_record,所以,我们可以通过next_record将记录连接起来,以单向链表的形式,所以这就决定了,当我们在记录链中寻找某记录时,只能顺序遍历,这也决定了一条数据链不会太长。

但一个页默认是16K,加上行溢出等处理,一页最多存放7992行记录,这么多的记录,必须顺序遍历么?当然不需要,让我看看页是怎么组织记录行的。

2与磁盘最小交互单位-- 页

作为与磁盘交互的最小单位,是用来存放实际数据的(页类型是b-tree node存真实数据,还有其他类型如索引目录页等用来加速查询)从上面的大图中可以大致看到一个页的整体结构:

如何理解并实现索引的原理和优化

让我们来看几个关键的字段参数:

Page Directory 决定着记录项在页内的查询效率

为了更快速的查询,页目录存储的本页的数据目录(槽),包含最大最小记录和 分组数据链的最大记录的偏移量。方便使用二分法快速查找数据,不需要再从最小值开始遍历,如下图:

如何理解并实现索引的原理和优化

图片来自《从根儿上理解 MySQL》

File Header决定页和页之间怎样关联

记录本页的一些通用信息,主要包含< 本页页号、上一页、下一页、页类型、所属表空间等等>。

通过页号来找到本页、通过上下页进行双向链表串联、通过类型判断是索引页还是数据页。。。

如何理解并实现索引的原理和优化

图片来自《从根儿上理解 MySQL》

此字段决定了页和页之间可以很方便的通过上述属性进行关联。

Page Header决定页的层级

存储的本页的数据信息,主要包含**<** 本页记录数量、在B+树中的层级、归属的索引ID、插入方向、最大事务ID等等 >。

有了页面的数据组织概念,那么,怎么利用这些结构来实现的数据快速查询呢?

Part3索引的演进思路

从上面的数据组织的知识里可以看到,行记录之间串联成单向链表,在每页中都按分组方式分布在此页的最小记录和最大记录之间。

页面之间通过上一页、下一页的指针,串联成双向链表,在磁盘中进行存储,如下图:

如何理解并实现索引的原理和优化

那么,要查询一条记录,可以怎么做?

3原始:顺序方式

如上图所示的数据串联方式,自然的提供了一种查询方式:即按主键顺序遍历每页和页中的记录行。

但是,这样的查询方式,除了在页内有二分优化,再无效率可言。怎么办?

寻求改进:既然页内的行记录可以分组入槽,那数据页之间为什么不行呢?

4改进:目录方式

我们将页向上聚蔟,构建一个页号目录,先在目录中查找,再到对应页中查找,就比顺序查找要快很多了。

如何理解并实现索引的原理和优化

寻求改进:这样的方式所需大量连续空间 + 目录会随数据变动而频繁变动,怎么办?

5演进:主键B+树方式

其实,在叙述行记录结构的时候,我们就看到,数据行的结构中,除了实际业务数据外,还有很多额外空间。

如record_type用来表示该记录的类型是数据还是索引。正是这些额外的空间的设计,给InnoDB以更加适合的方式组织索引提供了支持:

如何理解并实现索引的原理和优化

图片来自《从根儿上理解 MySQL》

这就是一棵B+树,页节点有层级区分,页中的行记录有类型区分。

业务数据都包含在叶子节点中,目录数据都包含在其他非叶节点中。

这样组织方式的优势,是允许足够少的层级容纳足够多的数据项(可以简单的假设每一页的数据项大小来预估)。

而这个索引方式就是我们常说的聚蔟索引。即使用主键值进行记录和页的排序,且叶子节点含有全部用户数据。

寻求改进:如果我想用其他列来查询,怎么办?

6扩展:二级索引、联合索引

二级索引

比如用户需要根据某一列(a列)的值来查询,那就再重新创建一个B+树。此索引树和聚蔟索引树的差别在于,索引节点是以a列的值为目录,且叶子节点只包含a列的值和主键两个值。

如果用户需要查询除c列以外的更多信息,则需要拿主键ID再去聚蔟索引查一次,也叫回表。

联合索引

二级索引是除主键外的单列索引,而联合索引则是多个列共同排序。假设用户需要用a 、b 两个列进行有序查询,那内在含义是,在a列值相同的情况下,再判断b的值。

同二级索引一样,InnoDB也需要再创建一棵B+树,且目录项的排序按先a,后b进行排序串联,叶子节点的数据项只包含 a 、b、主键三个值。

Part4生产实践之触类旁通

7美团定时任务索引优化[3]

系统需要定时的捞取特定时间段内特定状态、特定类型、特定操作者的任务进行定时处理。

select * from task   where     status=x     and operator_id=xxxx      and operate_time>xxxxxxxx01     and operate_time<xxxxxxxx99     and type=x;

开发发现此sql运行的越来越慢,希望给每个字段加二级索引,被优化师叫停,而是考虑的该表所有查询方式后,创建了一个联合索引:

(status,operator_id,type,operate_time)

为什么不建多个的二级索引?为什么范围查询的字段要放在最后?

分析:

(1)从前面的原理部分我们知道,索引是要占内存的,不是越多越好,能起作用就行。

(2)用于范围匹配的字段的索引位置要严谨。因为创建索引的时候,根据索引字段的顺序来进行排序,如果把time字段放在type字段前面建索引,在查询时,因为time是一个范围值,那么多个time值延续到type字段,整体是无序的,无法用到type索引。

8蚂蚁分布式主事务表的索引运用

蚂蚁的分布式事务中的主事务表起到了维护整体事务状态的作用,其中包含了整体事务状态、操作时间等字段。而在业务支付发生异常,且实时回滚失败时,需要事务恢复系统从远程捞取前1分钟的异常数据,并捞取对应的分支记录表发起异步回滚。

考虑查询效率,查询sql会限定业务发生时间在[前10分钟,前1分钟],是有范围查询,所以,针对其他字段,业务时间的索引顺序需要置于联合索引的最后。此操作的原理和上一部分美团定时任务的原理是一样的。

9阿里开发手册中几条典型的规范[4]

【强制】 在 varchar 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度。

原理关联:字段越长,索引占内存越多,只要其长度可以保证区分度即可

【强制】 字符搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决。

原理关联:左模糊的字段不是有序的,无法用到索引

【推荐】 如果有 order by 的场景,请注意利用索引的有序性。order by 最后的字段是组合索引的一部分,并且放在索引组合顺序的最后,避免出现 file_sort 的情况,影响查询性能。

原理关联:如果条件中有范围查询,则后续字段是无序的,order by时无法用到索引

【推荐】 建组合索引的时候,区分度最高的在最左边。

原理关联:区分度越高,查询路径越短,效率越高

感谢各位的阅读,以上就是“如何理解并实现索引的原理和优化”的内容了,经过本文的学习后,相信大家对如何理解并实现索引的原理和优化这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

您可能感兴趣的文档:

--结束END--

本文标题: 如何理解并实现索引的原理和优化

本文链接: https://www.lsjlt.com/news/61563.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何理解并实现索引的原理和优化
    这篇文章主要讲解了“如何理解并实现索引的原理和优化”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何理解并实现索引的原理和优化”吧!Part1为什么Kafk...
    99+
    2022-10-18
  • MySQL的索引原理以及查询优化详解
    目录一、介绍1.什么是索引?2.为什么要有索引呢?二、索引的原理一 索引原理二 磁盘IO与预读三、索引的数据结构四、Mysql索引管理一、功能二、MySQL的索引分类三、 索引的两大...
    99+
    2022-11-12
  • MySql如何查看索引并实现优化
    mysql中支持hash和btree索引。innodb和myisam只支持btree索引,而memory和heap存储引擎可以支持hash和btree索引 我们可以通过下面语句查询当前索引使用情况: show s...
    99+
    2022-05-28
    MySql 索引 优化
  • 深入解析MySQL索引的原理与优化策略
    目录索引的概念索引的原理索引的类型索引的使用索引的使用方式注意事项索引优化技巧索引的概念 mysql索引是一种用于加速数据库查询的数据结构,它类似于书籍的目录,能够快速指导我们找到需要的信息。MySQL索引可以根据一定的...
    99+
    2023-03-31
    解析MySQL索引原理和优化策略 MySQL索引原理 MySQL优化策略
  • 深入了解MySQL中索引优化器的工作原理
    目录本文导读一、mysql 优化器是如何选择索引的1、MySQL数据库组成2、MySQL数据库成本计算二、MySQL查询成本三、SELECT 执行过程总结本文导读 本文将解读MySQL数据库查询优化器(CBO)的...
    99+
    2022-11-09
  • MySQL数据库优化之索引实现原理与用法分析
    本文实例讲述了MySQL数据库优化之索引实现原理与用法。分享给大家供大家参考,具体如下: 索引 什么是索引 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行...
    99+
    2022-10-18
  • 如何理解Vue实现原理与前端性能优化
    这篇文章主要介绍“如何理解Vue实现原理与前端性能优化”,在日常操作中,相信很多人在如何理解Vue实现原理与前端性能优化问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解...
    99+
    2022-10-19
  • PHP与MySQL索引的原理和底层实现细节
    MySQL是一种非常流行的关系型数据库管理系统,而PHP是一种广泛用于开发Web应用程序的服务器端脚本语言。在开发Web应用程序时,经常需要与数据库进行交互,而索引是提高数据库查询性能的重要机制之一。本文将介绍PHP与MySQL索引的原理和...
    99+
    2023-10-21
    PHP MySQL索引 底层实现细节
  • Go 中的 NumPy 数组索引:如何实现和优化?
    Go 语言是一种快速而高效的编程语言,由于其速度和可扩展性,越来越多的开发人员开始将其用于数据科学和机器学习领域。而 NumPy 数组是 Python 中用于数值计算的核心库之一,它提供了一种高效的多维数组对象,以及处理这些数组的各种工具。...
    99+
    2023-06-27
    文件 numpy 索引
  • ASP.NET MVC 如何实现高效响应并利用索引优化?
    ASP.NET MVC 是一种用于 Web 应用程序开发的框架,它可以帮助开发人员快速创建高效、可扩展的应用程序。本文将介绍如何利用索引优化来实现 ASP.NET MVC 的高效响应。 什么是索引? 在数据库中,索引是一种用于加速数据检索...
    99+
    2023-08-11
    索引 响应 spring
  • Go语言中数组索引和存储的实现原理是什么?
    Go语言是一门功能强大的编程语言,它拥有很多独特的特性,比如强类型、垃圾回收机制和原生支持并发等。其中,数组是Go语言中最基本的数据结构之一,它在很多场景下都有着广泛的应用。本文将介绍Go语言中数组索引和存储的实现原理。 数组的定义和初始...
    99+
    2023-11-06
    索引 数组 存储
  • 如何在MongoDB中实现数据的索引和查询优化功能
    如何在MongoDB中实现数据的索引和查询优化功能近年来,随着大数据的兴起,数据存储和查询变得越来越复杂。对于数据量较大的应用来说,索引和查询优化就成了至关重要的任务。MongoDB是一种非关系型数据库,由于其面向文档的特点,使得其在处理海...
    99+
    2023-10-22
    数据库性能 查询优化 MongoDB索引
  • LeetCode算法如何优化PHP中的索引对象实现?
    在PHP中,索引对象是一种非常常见的数据结构,可以用来快速访问和操作数组中的元素。然而,当数组非常大时,索引对象的实现可能会变得非常低效。本文将介绍如何使用LeetCode算法来优化PHP中的索引对象实现,从而提高程序的性能。 什么是索...
    99+
    2023-09-01
    索引 对象 leetcode
  • 如何在 Python 中实现高效的索引和日志处理?
    Python 作为一种强大的编程语言,广泛应用于各种领域。在实际应用中,很多任务都需要对数据进行索引和日志处理,这是一种非常基础的操作。在本文中,我们将介绍如何在 Python 中实现高效的索引和日志处理。 一、索引 索引是一种非常常见的数...
    99+
    2023-10-20
    索引 日志 面试
  • PHP并发处理:如何优化对象的Shell脚本实现?
    在现代计算机应用程序中,处理并发任务已经成为一个非常重要的任务。对于PHP来说,处理并发任务有很多种方式,其中一种比较常见的方式是通过Shell脚本来实现。本文将介绍如何使用Shell脚本来实现PHP并发处理,并提供一些优化技巧。 一、S...
    99+
    2023-10-22
    对象 并发 shell
  • 如何实现MySQL底层优化:查询优化器的工作原理及调优方法
    如何实现MySQL底层优化:查询优化器的工作原理及调优方法在数据库应用中,查询优化是提高数据库性能的重要手段之一。MySQL作为一种常用的关系型数据库管理系统,其查询优化器的工作原理及调优方法十分重要。本文将介绍MySQL查询优化器的工作原...
    99+
    2023-11-08
    MySQL 查询优化器 调优方法。
  • 如何处理Go语言中的并发文件的文件检索和索引问题?
    如何处理Go语言中的并发文件的文件检索和索引问题?在实际开发中,经常需要处理大量的文件,并且需要对这些文件进行检索和索引。而在Go语言中,我们可以使用并发编程的方式来提高文件处理的效率。本文将介绍如何使用Go语言处理并发文件的文件检索和索引...
    99+
    2023-10-22
    并发处理 (concurrency) 文件检索 (file search) 索引问题 (indexing issue)
  • 了解Python文件索引的工作原理,轻松实现文件快速加载。
    Python文件索引是Python解释器在加载模块时用来快速查找文件位置的一种机制。它通过在模块搜索路径中建立索引缓存,从而实现了文件位置的快速定位。在本文中,我们将详细介绍Python文件索引的工作原理,并演示如何使用它来实现文件的快速加...
    99+
    2023-09-28
    文件 索引 load
  • 如何实现MySQL底层优化:索引的高级最佳实践和维护策略
    对于MySQL数据库的底层优化,索引的高级最佳实践和维护策略是至关重要的。通过合理地创建和维护索引,可以大大提升数据库的性能和查询效率。本文将介绍MySQL索引的高级最佳实践和维护策略,并提供具体的代码示例,帮助读者更好地掌握这一关键知识。...
    99+
    2023-11-08
    最佳实践 MySQL索引优化 数据维护策略
  • 索引和自然语言处理:如何在Go和Django中实现快速搜索
    随着互联网的发展和信息爆炸式的增长,快速搜索已经成为了我们日常生活中必不可少的一部分。搜索引擎的出现,让我们在海量信息中迅速找到我们需要的内容。但是,搜索引擎的背后是怎样的技术支持呢?这就涉及到了索引和自然语言处理技术。 本文将介绍如何在...
    99+
    2023-08-26
    django 自然语言处理 索引
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作