SQL进阶理论篇(九):为什么不存在完美的索引

news2024/11/29 20:47:59

文章目录

  • 简介
  • 索引片和过滤因子
  • 如何通过宽表避免回表
  • 什么是过滤因子
  • 理想索引设计:三星索引
  • 为什么很难存在理想的索引设计?
  • 参考文献

简介

本节将主要介绍以下部分:

  • 什么是索引片,什么是过滤因子?
  • 设计索引的时候,可以遵循哪些原则
  • 为什么理想的索引很难应用在实际工作中?

索引片和过滤因子

索引片就是SQL查询语句在执行时需要扫描的一个索引片段,我们会根据索引片中包含的匹配列的数量的不同,将索引分为窄索引和宽索引。其中窄索引一般指包含索引列数为1或者2,宽索引一般指列数大于2。

如果索引片越宽,那么可能需要顺序扫描的索引页就越多;如果索引片越窄,在一定程度上就可以减少索引访问的开销。

比如,在product_comment表中,comment_id为主键,我们可以设置(user_id)为窄索引,也可以设置其他所有字段(user_id, product_id,comment_text)为宽索引。

如图:

在这里插入图片描述

需要说明的是,每个非聚集索引(二级索引)里都会保存主键值,然后通过主键值,去磁盘上回表来查找相应的记录行(二次操作,所以叫做二级索引)。因此每个索引都相当于包括了主键

所以我们在声明窄索引(user_id)的时候,其实就相当于声明了(comment_id,user_id)。我们声明宽索引(user_id, product_id,comment_text)时,就相当于声明了(comment_id,user_id, product_id,comment_text),覆盖了全表字段。

如何通过宽表避免回表

宽索引需要顺序扫描的索引页很多,但也是有好处的,在多数情况下,它可以不需要回表,直接从索引树里拿数据就可以(需要的字段都是索引)。

回表指的就是,数据库在根据索引找到了主键之后,还需要通过主键再次到数据表中去读取对应记录行的过程。

教程里举了个例子,来讲解使用不同的索引片来运行相同查询时的时间差异。

比如,先以窄索引(user_id)来执行下面语句:

SELECT comment_id, product_id, comment_text, user_id FROM product_comment WHERE user_id between 100001 and 100100

返回110条记录,耗时0.062s。

接着我们再以宽索引(user_id, product_id, comment_text)运行上面语句,结果相同,耗时为0.043s。

可以看到,查询效率会有一些提升。这就是因为select中需要的列都在宽索引里,数据库直接扫描索引树就可以,不需要再回表了,所以一定程度上提升了SQL查询的效率。

什么是过滤因子

在设计索引片的时候,我们还需要考虑一个辅助因素,就是过滤因子

过滤因子,描述了谓词的选择性。

什么是谓词呢?

在where条件语句中,每一个条件都称为一个谓词。因此谓词选择性,实际上就等于满足这个条件列的记录数除以总记录数的值。可以理解成满足条件的记录数比例。

比如说我们有一个player球员表,其中有team_id,height、name、gender等字段,然后gender的取值都是male。

接下来我们评估下这些过滤因子的筛选能力:

在这里插入图片描述

可以看到,gender和team_id都不是一个好的过滤因子,单值比例有些过于高了。相比之下,过滤因子筛选能力最强的,是name字段。

那如果我们创建一个联合过滤条件,如(height, team_id),它的过滤能力如图:

在这里插入图片描述

可以看到联合过滤因子的过滤性是很强的。

不过需要注意,在联合的时候,各组成条件的关联性应该尽量互相独立,如果列和列之间具有相关性,那么创造出来的联合过滤因子,过滤效果就会差很多。

因此,过滤因子实际上决定了索引片的大小,即索引片中的记录数。过滤因子的条件过滤能力越强,满足条件的记录数就越少,索引片也就越小。

理想索引设计:三星索引

在索引的设计里,确实存在一种规范,叫做三星索引规范,其在索引设计中的地位相当于3NF在数据表设计中的地位。

三星索引具体是指:

  • 在where条件语句中,找到所有等值谓词中的条件列,将它们作为索引片中的开始列;
  • 将group by和order by的列也加入索引;
  • 将select字段中剩余的列加入索引片。

如此下来,我们的索引片基本会变成一个宽索引,近乎涵盖了所有能添加的相关列。那么对于一条查询来说,这样做的效率是最高的码?

一般来讲,是的。

首先,将where中的等值谓词加入索引片,借助索引进行过滤,效率自然是高的。

其次,将group by和order by中的列也加入索引,可以有效避免进行file sort排序,因为创建了索引就会按照索引顺序来存储数据,二次分组或者排序的时候就会提升效率。

最后,select中列加入索引。好处更明显了,就是避免回表现象。所有的列都在索引树里了,还回表去读什么记录行?节省了IO,自然就快了。

为什么很难存在理想的索引设计?

三星索引设计这么高效,那是不是大家都用三星索引就可以了?

那当然不是,三星索引的缺点也很明显。主要有以下几点:

  • 索引片太宽了。一个索引片十几二十列,那么单个页能放的索引数据就少了,要读取相同数量的索引数据的话,就要去读更多的页,在极端情况下,很难说效率还会不会高。
  • 如果数据量过大,比如说成百上千万行,那么存储它们的索引,也需要占用很大的磁盘,而且这么多索引,带给缓冲池空间的压力也很大。
  • 索引维护的成本很高。当新数据进来的时候,就需要重构索引,当成百上千的数据进来呢?这个时间和计算资源的消耗是很大的。

因此,我们实际使用的时候,还是需要权衡的,而且大多数情况下,我们还是会像反范式设计一样,反三星式设计。

  • 单个表,索引不宜过多,否则增加/修改数据时,对索引的修改会造成额外的消耗。
  • 定期检查索引使用情况,对于使用频率低的索引,可以及时删除。
  • 控制索引片中的索引列数量。通常我们会把where中的条件列加入索引,而select里的不会。
  • 尽量使用数值类型代替字符类型来构建索引,避免使用字符类型做主键,对字符字段最好只建前缀索引。在 MySQL InnoDB 中,系统默认单个索引长度最大为 767 bytes,如果单列索引长度超过了这个限制,就会取前缀索引,也就是取前 255 字符。这实际上也是告诉我们,字符列会占用较大的空间

看到一条很有趣的评论,他说"所谓的三星索引,其实就是面向查询建了个表"。哈哈哈哈哈哈,我觉得他说的很有道理。

参考文献

  1. 29丨为什么没有理想的索引?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1318156.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python装饰器新境界:详解装饰器重载内置操作

更多Python学习内容:ipengtao.com 大家好,我是彭涛,今天为大家分享 Python装饰器新境界:详解装饰器重载内置操作,全文3900字,阅读大约15分钟。 Python装饰器重载内置操作,我们通常指的是使用装饰…

Sqoop安装与配置-shell脚本一键安装配置

文章目录 前言一、使用shell脚本一键安装1. 复制脚本2. 增加执行权限3. 执行脚本4. 加载用户环境变量5. 查看是否安装成功 总结 前言 本文介绍了如何使用Shell脚本一键安装Sqoop。Sqoop是一个用于在Apache Hadoop和结构化数据存储(如关系数据库)之间传输…

Source Insight使用

之前一直使用VS code阅读kernel源码,有时候函数跳转有些问题。最近换成了Source Insight软件,发现真不错。就是需要一些学习成本,简单记录一下如何使用吧。 1、下载安装: 首先肯定是要下载安装,这个就不写了&#xf…

FFmpeg——在Vue项目中使用FFmpeg(安装、配置、使用、SharedArrayBuffer、跨域隔离、避坑...)

个人简介 👀个人主页: 前端杂货铺 🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…

滑动窗口训练

1.原理 我们用这道题目 LCR 008. 长度最小的子数组 来讲解“滑动窗口”的解法。 1.1.暴力解法 遍历每一个子数组(都要大于等于 7),最统计出最小的数组。 这样做的话,划分左右区间(left 和 right)就需要…

怎样长时间保持SSH会话连接不断开?

操作场景 使用SSH方式登录CentOS Stream操作系统的云服务器时,过一段时间就会自动断开连接。 该文档适用于CentOS/EulerOS系统。 操作方法 编辑/etc/ssh/sshd_config文件设置心跳,保持连接。 编辑/etc/ssh/sshd_config,添加配置项&#x…

Flink系列之:监控反压

Flink系列之:监控反压 一、反压二、Task 性能指标三、示例四、反压状态 Flink Web 界面提供了一个选项卡来监控正在运行 jobs 的反压行为。 一、反压 如果你看到一个 task 发生 反压警告(例如: High),意味着它生产数…

Android动画

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。 目录 一、导读二、概览三、动画实现3.1 帧动画资源文件中实现…

Linux线程的设计

文章目录 一.理解Linux线程的本质进程地址空间是进程访问系统资源的窗口Linux系统中,线程是比进程更轻量级的执行流 二.Linux线程独立运行的原理三.基础线程控制 一.理解Linux线程的本质 进程地址空间是进程访问系统资源的窗口 Linux系统中,线程是比进程更轻量级的执行流 线程…

IIS如何本地部署网站,作为局域网内的服务器

文章目录 IIS本地部署WebService1.使用IIS及WebService的原因:2.相关文件说明及网络条件说明:(1)文件说明:(2)网络条件说明: 3.IIS安装与配置:第一步:安装第二步&#xf…

全国职业院校技能大赛“大数据应用开发”赛项说明

1、赛项介绍 (1)赛项名称 全 国 职 业 院 校 技 能 大 赛 “大数据应用开发” 赛 项 职业院校技能大赛官网 (vcsc.org.cn)https://www.vcsc.org.cn/ 大赛组织机构介绍 全国职业院校技能大赛(以下简称大…

Python 爬虫开发完整环境部署,爬虫核心框架安装

Python 爬虫开发完整环境部署 前言: ​ 关于本篇笔记,参考书籍为 《Python 爬虫开发实战3 》 笔记做出来的一方原因是为了自己对 Python 爬虫加深认知,一方面也想为大家解决在爬虫技术区的一些问题,本篇文章所使用的环境为&#x…

网络攻击1——网络安全基本概念与终端安全介绍(僵尸网路、勒索病毒、木马植入、0day漏洞)

目录 网络安全的基本术语 黑客攻击路径 终端安全 僵尸网络 勒索病毒 挖矿病毒 宏病毒 木马的植入 0day漏洞 流氓/间谍软件 网络安全的基本术语 网络安全的定义(CIA原则) 数据的保密性Confidentiality(对称/非对称秘钥) …

mysql innodb知识记录

官方文档 官网架构图 innodb 特性 内存 buffer pool 采用优化后的LRU算法, 3/8 of the buffer pool is devoted to the old sublist.The midpoint of the list is the boundary where the tail of the new sublist meets the head of the old sublist.When In…

C语言-Makefile

Makefile 什么是make? make 是个命令,是个可执行程序,用来解析 Makefile 文件的命令这个命令存放在 /usr/bin/ 什么是 makefile? makefile 是个文件,这个文件中描述了我们程序的编译规则咱们执行 make 命令的时候, m…

[DroneCAN]CAN-Convertor控制CAN电调电机

简介 CAN电调电机是一类通过CAN协议控制转速的电调电机,和传统的PWM电调电机不同在于,CAN协议有网络性和抗干扰性,因此其性能比PWM更好,占用的端口数也会更少。在apm或者px4等基于dronecan的飞控来说,想要控制第三方的…

【CMU 15-445】Lecture 10: Sorting Aggregations Algorithms 学习笔记

Sorting & Aggregations Algorithms SortingTop-N Heap SortExternal Merge Sort2-WAY External Merge SortK-WAY External Merge SortDouble Buffering Optimization AggregationsSortingHashing 本节课主要介绍的是数据库系统中的排序算法以及聚合算法 Sorting 排序算法…

大模型自定义算子优化方案学习笔记:CUDA算子定义、算子编译、正反向梯度实现

01算子优化的意义 随着大模型应用的普及以及算力紧缺,下一步对于计算性能的追求一定是技术的核心方向。因为目前大模型的计算逻辑是由一个个独立的算子或者说OP正反向求导实现的,底层往往调用的是GPU提供的CUDA的驱动程序。如果不能对于整个计算过程学习…

LearnDash LMS ProPanel在线学习系统课程创作者的分析工具

点击阅读LearnDash LMS ProPanel在线学习系统课程创作者的分析工具原文 LearnDash LMS ProPanel在线学习系统课程创作者的分析工具通过整合报告和作业管理来增强您的 LearnDash 管理体验,使您能够发送特定于课程的通信,并显示课程的实时活动&#xff01…

分类信息网商业运营版源码系统:适合各类行业分类站点建站 带安装部署教程

随着互联网的快速发展,信息分类网站在各个行业中得到了广泛应用。为了满足不同行业的需求,罗峰给大家分享一款适合各类行业分类站点建站的商业运营版源码系统。该系统旨在提供一套完整的解决方案,帮助用户快速搭建自己的分类信息网站&#xf…