数据库优化之索引

article/2025/10/17 3:00:24

一、什么是索引

索引是对数据库表中一列或多列的值进行排序的一种结构数据,使用索引可快速访问数据库表中的特定信息。

数据库索引是创建在表的某列上的,并且存储了这一列的所有值。同时存储了指向表中的相应行的指针。

二、索引的分类

唯一索引
唯一索引是不允许其中任何两行具有相同的值的索引。例如,如果在employee表中职员的姓(lname)上创建了唯一索引,则任何两个员工都不能同姓。关键字UNIQUE

主键索引
在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。关键字PRIMARY

常规索引
快速定位特定数据

全文索引
全文索引查找的是文本中的关键词,而不是比较索引中的值,关键字FULLTEXT

在InnoDB中根据索引的存储形式,又可以分为一下两种
在这里插入图片描述聚集索引选取规则:
● 如果存在主键,主键索引就是聚集索引
● 如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引
● 如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏的聚集索引

回表查询
在这里插入图片描述通过二级索引查询到主键,再根据主键去聚集索引中查询一行的数据,称为回表查询

复合引列
可以基于数据库表中的单列或多列创建索引。在业务场景中,如果存在多个查询条件,建议使用联合索引而非单列索引

三、索引的优缺点

优点:
1、通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
2、大大加快数据的检索速度。
3、可以加速表和表之间的连接。
4、在使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间。
5、通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

缺点:
1、创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。
2、索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。
3、当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度。

四、索引语法

● 创建索引:

CREATE [UNIQUE|FULLTEXT] INDEX index_name ON table_name(index_col_name);

● 查看索引:

SHOW INDEX FROM table_name;

● 删除索引:

DROP INDEX index_name ON table_name;

● 查看索引的使用情况:

SHOW status like ‘Handler_read%'

handler_read_key:这个值越高越好,越高表示使用索引查询到的次数。
handler_read_rnd_next:这个值越高,说明查询低效。

五、索引失效的情况

(1)违背最左前缀法则
如果索引了多列(联合索引),要遵守最左前缀法则。是指查询从索引的最左列开始(索引中的最左列必须存在,跟在SQL语句中的位置无关),并且不跳过索引中的列。如果跳跃某一列,索引将部分失效(后面的字段索引失效),如果缺少了索引的最左列,索引将全部失效。
(2)联合索引中出现范围查询
联合索引中出现范围查询(>,<),范围查询右侧的列索引失效,所以在业务允许的情况下尽量使用 >= 或 <=
(3)在索引列上进行运算或使用函数
where 子句里对索引列上有数学运算或者使用函数,索引失效。
(4)索引列与条件列字段类型不匹配
如果列类型是字符串,要在条件中将数据使用引号引用起来,否则索引失效。
(5)以%开头的模糊查询
以‘%’开头的like查询会导致索引失效。以‘%’结尾,索引不会失效。
(6)多条件查询使用or连接
多条件查询时使用or连接条件,索引会失效。要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引。
(7)数据分布影响
如果MySQL评估使用全表扫描要比使用索引快,则不使用索引,比如数据量极少的表或者表中的绝大部分数据都满足条件。

六、索引优化方案

(1)索引不要建立在重复值较多的字段上,比如性别
(2)合理使用覆盖索引,减少回表
(3)合理控制索引的数量,一般不超过六个,因为索引在提高查询效率的同时会降低insert和update的效率(可能会重建索引)
(4)避免索引失效
(5)用 force index 命令强制使用某个索引
(6)当字段类型为字符串时,可以只将字符串的一部分前缀做为索引

七、不适合创建索引的情况

1、很少使用或者参考的列不应该创建索引。
2、值分布很稀少的列不适合建索引。比如性别。
3、频繁更新的字段不适合创建索引。
4、定义为text, image和bit数据类型的列不应该增加索引。
5、当修改性能远远大于检索性能时,不应该创建索引。

八、索引的数据结构

首先,数据库索引使用树来存储,因为树的查询效率高,而且二叉查找树还可以保持数据的有序。
为了减少内存的占用,数据库索引是存储在外部磁盘上。Mysql衡量查询效率的标准就是磁盘IO次数。
如果利用二叉树作为索引结构,那么磁盘的IO次数和索引树的高度是相关的。为了提高查询效率,就需要减少磁盘IO数。为了减少磁盘IO的次数,就需要尽量降低树的高度,需要把原来“瘦高”的树结构变的“矮胖”,树的每层的分叉越多越好,B树正好符合我们的要求,这也是B树的特征之一。
B树(B类树)的特点就是每层节点数目非常多,层数很少,目的就是为了就少磁盘IO次数。
B树是一种多路平衡查找树,它的每一个节点最多包含K个孩子,k称为B树的阶。k的大小取决于磁盘页的大小。

MySQL的索引是在存储引擎层实现的,不同的存储引擎有不同的结构,主要包含以下几种:

索引结构描述
B+Tree索引最常见的索引类型,大部分引擎都支持B+Tree索引
Hash索引底层数据结构是用哈希表实现的,只支持精确匹配,不支持范围查询
R-tree(空间索引)空间索引是MyISAM引擎的一个特殊索引类型,主要用于地理空间数据类型,通常使用较少
Full-text(全文索引)是一种通过建立倒排索引,快速匹配文档的方式。类似于Lucene,Solr,Es

一个m阶的B树具有如下几个特征:
1、根结点至少有两个子女。
2、每个中间节点都包含k-1个元素和k个孩子,其中 m/2 <= k <= m。
3、每一个叶子节点都包含k-1个元素,其中 m/2 <= k <= m。
4、所有的叶子结点都位于同一层。
5、每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域分划。

B树结构
在这里插入图片描述
一个m阶的B+树具有如下几个特征:
1、有k个子树的中间节点包含有k个元素(B树中是k-1个元素),每个元素不保存数据,只用来索引,所有数据都保存在叶子节点。
2、所有的叶子结点中包含了全部元素的信息,及指向含这些元素记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。
3、所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素。

B+树结构
在这里插入图片描述
B+树和B树的区别:
1、单一节点存储更多的元素,使得查询的IO次数更少。
2、所有查询都要查找到叶子节点,查询性能稳定。
3、所有叶子节点形成有序链表,便于范围查询。
4、B+树中间节点没有存储数据,只有叶节点存放数据,而B树每个索引节点都会有Data域。

红黑树的特点:
1、节点是红色或黑色。
2、根节点是黑色。
3、每个叶子节点都是黑色的空节点(NIL节点)。
4、每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)
5、从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
6、从根到叶子的最长路径不会超过最短路径的2倍。

红黑树结构:
在这里插入图片描述
什么情况下使用红黑树?红黑树和B树使用场合有什么不同?
1、两者都是有序的数据结构,可用作数据容器。
2、红黑树多用在内部排序,即全放在内存中的,微软STL的map和set的内部实现就是红黑树。
3、B树多用在内存里放不下,大部分数据存储在外存上时。因为B树层数少,因此可以确保每次操作,读取磁盘的次数尽可能的少。 在数据较小,可以完全放到内存中时,红黑树的时间复杂度比B树低。反之,数据量较大,外存中占主要部分时,B树因其读磁盘次数少,而具有更快的速度。

注意:
1、B-树和B树是同一概念,翻译不同所致。
2、度数:在树中,每个节点的子节点(子树)的个数就称为该节点的度(degree)。
3、阶数:(Order)阶定义为一个节点的子节点数目的最大值。(自带最大值属性)


http://chatgpt.dhexx.cn/article/M9AtooZv.shtml

相关文章

数据库性能优化方案

数据库优化方案 前言数据库性能优化方案SQL 调优表结构优化硬件优化架构优化分库分表详解分库单应用单数据库多应用单数据库多应用多数据库 分表水平拆分和垂直拆分单库内拆分和多库拆分 分库分表带来的复杂性跨库关联查询分布式事务排序、分页、函数计算问题分布式 ID多数据源…

Escaping closure captures non-escaping parameter 'xx'

新版的Swift闭包做参数默认是noescaping&#xff0c;不再是escaping。 如果函数里执行该闭包&#xff0c;要添加escaping。

Escaping closure captures non-escaping parameter ‘findPeripheral‘

文章目录 1.问题2.原因和解决参考连接 1.问题 2.原因和解决 逃逸闭包前面没有加escaping关键字&#xff0c;加上就可以了&#xff0c;如下图 参考连接 stack overflow 官方文档&#xff1a;Escaping Closures

[plugin:commonjs] Unexpected ‘/‘. Escaping special characters with \ may help.错误分析

错误原因&#xff1a;样式表里使用了//作注释 解决办法&#xff1a;把‘//tab样式’去掉就可以了 补充&#xff1a;css中注释使用‘/**/’

swift3.0中@escaping 和 @noescape 的含义

swift3.0中escaping 和 noescape 的含义 开始用swift语言是很容易的&#xff0c;而且它确实是一门很吸引人的语言。但是随着你频繁的使用&#xff0c;你会逐渐接触到swift更加复杂的结构. 在swift2中&#xff0c;你可能遇到过noescape属性&#xff0c;你有没有花一点时间去理解…

SwiftUI 内功之 ViewBuilder 和escaping 组合使用传递View (教程含源码)

实战需求 SwiftUI 内功之 ViewBuilder 和escaping 组合使用传递View 本文价值与收获 看完本文后,您将能够作出下面的界面 看完本文您将掌握的技能 ViewBuilderescaping基础知识 ViewBuilder 一个自定义参数属性,用于从闭包构造视图。 struct ViewBuilder总览 您通常将…

quote mysql_【原创】11. MYSQL++ 之 Quoting 与 Escaping

1. 综述 其实一看到这两个单词的时候我有点莫名其妙&#xff0c;可能英语没有学好&#xff0c;我的理解就是quoting是“引用”的意思&#xff0c;而Escaping是“逃脱”的意思。后来在看到了作者的TUTORIAL之后才大致明白了两者的意思。 QUOTING大白话就是为SQL语句打上单引号。…

错误日志:Syntax Error: Error: Unexpected ‘/‘. Escaping special characters with \ may help.

在运行Vue项目的时候出现错误&#xff1a; ERROR Failed to compile with 1 error 9:55:33error in ./src/components/index/SimpleHeader/index.vue?vue&t…

swift_041(Swift的@noescape和@escaping)

noescape在swift3.0中已经被废弃&#xff0c;在swift3.0中noescape被用作一个默认值。 escaping属性写在参数类型的前面而不是参数名称的前面。这是swift3里一个新的点。 这里需要先介绍一下escape的概念。当一个闭包当做一个参数传进函数里&#xff0c;这个闭包是在这个函数执…

swift函数参数指针传递inout和@escaping冲突的解决方法

这里写目录标题 需求解决方法容易产生的问题总结 今天深入解决关于函数参数指针的问题。问题是这样&#xff0c;我在swift的一个函数里面&#xff0c;参数里需要传递一个指针类型的Int&#xff0c;但是这个函数里面还有一个逃逸闭包escaping,于是就会报错这样&#xff1a;Escap…

Using the “escape“ directive (legacy escaping) is not allowed when auto-escaping is on with a markup

springboot 2.3.0版本以上&#xff0c;springboot自动引用freemarker模板文件的后缀从.ftl变成了.ftlh <!DOCTYPE html> <#escape x as x?html> <#include "../common/macro.ftl"> <html lang"en"> </html> </#escape&…

Escaping closure captures non-escaping parameter ‘xx‘

新版的Swift闭包做参数默认是noescaping&#xff0c;不再是escaping。 如果函数里执行该闭包&#xff0c;要添加escaping。

Swift中的逃逸闭包(@escaping )与非逃逸闭包(@noescaping)

逃逸闭包 概念&#xff1a;一个接受闭包作为参数的函数&#xff0c;该闭包可能在函数返回后才被调用&#xff0c;也就是说这个闭包逃离了函数的作用域&#xff0c;这种闭包称为逃逸闭包。当你声明一个接受闭包作为形式参数的函数时&#xff0c;你可以在形式参数前写escaping来…

VMware创建Linux虚拟机之(三)Hadoop安装与配置及搭建集群

Hello&#xff0c;world&#xff01; &#x1f412;本篇博客使用到的工具有&#xff1a;VMware16 &#xff0c;Xftp7 若不熟悉操作命令&#xff0c;推荐使用带GUI页面的CentOS7虚拟机 我将使用带GUI页面的虚拟机演示 虚拟机&#xff08;Virtual Machine&#xff09; 指通过…

hadoop安装及简单的使用

hadoop安装及简单的使用 一、hadoop运行环境搭建二、hadoop 目录结构三、hadoop 本地模式四、hadoop 伪分布式模式五、伪分布式 YARN 运行六、伪分布式启动历史服务器七、伪分布式配置日志的聚集八、hadoop 集群模式 一、hadoop运行环境搭建 1.环境准备 安装 hadoop 需要使用 …

hadoop安装(window10)

一、下载和winutils 1.下载&#xff1a;http://archive.apache.org/dist/hadoop/core/ 官网下载&#xff1a;http://hadoop.apache.org/releases.html &#xff08;提供最新的几个版本&#xff09; https://github.com/steveloughran/winutils&#xff08;windows安装需要&…

Hadoop安装与配置

第一步&#xff1a;装虚拟机 我把hadoop安装需要的文件放在下面大家自行去取&#xff1a; 百度网盘 请输入提取码 提取码&#xff1a;8888 由于centos镜像文件太大传不上去需要的话可以加我qq:364960241 目录 第一步&#xff1a;装虚拟机 第二步&#xff1a;配置静态网络…

基于CentOS虚拟机的Hadoop安装教程(自用备忘)

该博文是用于记录Hadoop的安装过程&#xff0c;且记录其中出现的一些问题&#xff0c;防止日后遗忘 实验环境&#xff1a; 虚拟机&#xff1a;CentOS7Hadoop&#xff1a;3.3.2java&#xff1a;java 8u331下载连接&#xff1a; CentOS&#xff1a;centos-7-x86_64-dvd-2009.iso…

Hadoop安装与配置详细教程

【确保服务器集群安装和配置已经完成&#xff01;】 前言 请根据读者的自身情况&#xff0c;进行相应随机应变。 我的三台CentOS7服务器&#xff1a; 主机&#xff1a;master&#xff08;192.168.56.110&#xff09; 从机&#xff1a;slave0&#xff08;192.168.56.111&…

Hadoop安装教程 Linux版

Hadoop安装教程 Linux版 一、Linux虚拟机安装 方法一&#xff1a;使用Windows下Linux子系统&#xff08;大佬可选&#xff09; 方法二&#xff1a;使用VMware安装Linux虚拟机&#xff08;小白可选&#xff09; 方法三&#xff1a;安装双系统&#xff08;不怕麻烦的可以试试&am…