数据库性能系列之索引(上)

前言

上一次,我们从优化子查询的角度,讲解了一些简单的数据库性能优化方面的知识。通过优化子查询的顺序,包括合理使用IN和EXISTS,可以起到部分查询的效率提升。

但对于其他大多数场景,如单表记录很大,或多表级联查询包含条件或排序时,子查询的优化往往起不到决定性的效果。所以从今天开始,我们要逐渐接触这一部分的主角:索引。这部分内容我会分为上中下三篇进行详细的讲解,上篇会着重于索引的概念,以及基础的使用方式;中篇会讲解索引背后的实现原理,便于理解索引如何发挥作用;下篇会结合一些复杂的SQL场景,来描述索引在实际工作中如何使用。

概述

数据库中的索引,就像一本书的目录,它可以帮我们快速定位和查找,从而加快数据查询的效率。

如果我们不使用索引,那么记录就必须从表中第一行开始进行逐行扫描,直到找出符合条件的记录为止,这样的查询效率,必然是很低的。那么,索引是不是建立得越多就越好呢?

答案是否定的,因为索引也是一种存储在数据库硬盘中的数据结构,会占用一定的空间。而且对于数据的新增、修改和删除时,数据库也需要对其相关的索引进行更新,进而降低了整体效率。

索引的类型

了解了索引的基本概念之后,我们还需要知道不同索引的用途。索引从功能逻辑上可以分为四类:普通索引、唯一索引、主键索引和全文索引。而在物理实现上可以分为两类:聚集索引和非聚集索引。下面我们来逐一讲解:

1、普通索引:最基础的索引,没有任何约束,直接建立即可,用于提升查找的效率。

2、唯一索引:在普通索引的基础上,加入了数据唯一性的约束,用于检查数据是否唯一,在同一张数据表中,可以有多个唯一索引。

3、主键索引:在唯一索引的基础上,加入了NOT NULL的特性,在我们给数据库表设置主键时,会自动创建主键索引,而根据主键的特性,一个表中只能有一个主键索引。

4、全文索引:一种特殊的基于标记的索引,由数据库引擎维护,用于快速查找某个字符出现的位置,较少使用。目前此种查找一般会使用搜索引擎实现,如ES(ElasticSearch)。

5、聚集索引:确定了数据存储的顺序,在物理上是连续存储的,因此聚集索引在每个表中只能有一个。在默认情况下,数据库会对主键约束自动创建聚集索引,这就是数据表中的行记录通常按照主键排列的原因。

6、非聚集索引:在数据库中有单独的空间进行存储,索引项本身是按照顺序存储的,但是索引指向的内容却是随机存储的。也就是说非聚集索引在工作时,系统会进行两次查找,第一次会找到索引本身,第二次则根据索引对应的位置找出数据行。非聚集索引不会把索引指向的内容像聚集索引一样直接放到索引后面,而是维护单独的索引表,为数据的检索提供方便。由于实现原理的不同,非聚集索引在每个表中可以有多个。

索引的应用

现在我们来看一下索引使用的实际效果,目前我有一张表T_ORG_USER,其中大约有3000条数据。这时我们需要查询一条记录如下:

254e2f477a7227bd076e3e828d644e9c.png

我们可以使用主键Id和用户名分别查询同一条记录,然后查看查询记录的区别,首先我们使用主键Id进行查询:

SET STATISTICS TIME ON
SELECT * FROM T_ORG_USER WHERE F_USER_ID = 8400

查询结果如下图所示,执行时间为0毫秒:

35d8152d7b1e72f831ba3421ba446e26.png

此时,我们再使用用户名进行查询,用户名字段没有建立索引:

SET STATISTICS TIME ON
SELECT * FROM T_ORG_USER WHERE F_NAME = '24'

查询结果如下图所示,执行时间为196毫秒:

5b29b9a1a1fda4b2cbc47b66a3222003.png

从执行时间上,我们可以看出二者有明显的效率差别,这时我们再对F_NAME字段建立索引:

CREATE INDEX IDX_USERNAME ON T_ORG_USER(F_NAME)

再次查询,结果如图所示,执行时间缩短到了5毫秒:

989db543bd570fe4a9a4f084b676edcb.png

从上述三次的执行结果中,我们可以总结出以下两点:

1、对WHERE条件后的字段进行索引,可以大幅度提高查询的效率

2、采用聚集索引的查询效率,比采用非聚集索引的查询效率略高。在我们上述的例子中,第一次使用主键进行查询,系统会使用聚集索引进行查找,而第三次我们使用非聚集索引进行查找,效率会降低。因此在需要多次查询的场景下,我们的SQL语句应尽量使用主键索引进行查询。

除了我们之前描述的几种索引类型之外,索引还可以根据字段个数分为单一索引联合索引

单一索引是指使用单个列创建的索引,如我们上述的IDX_USERNAME所示,而把多个列组合在一起创建的索引,叫做联合索引。

创建联合索引时,我们需要注意字段的顺序问题,因为字段(a,b,c)和字段(b,a,c)创建出的联合索引,在使用时查询效率可能会不同。

导致这样的原因是由于联合索引存在最左匹配原则,也就是说如果我们创建了联合索引(a,b,c)时,WHERE条件如果为WHERE a = 1 AND b = 2 AND c = 3,则会匹配上联合索引,如果条件为WHERE b = 2,那么联合索引会失效,查询就会走全表扫描的方式去查找。还有一些范围查找操作也会导致联合索引失效,如果某一列使用了<,<=,>,>=,between等,那么此列后面的列就无法使用到索引。

总结

今天我们讲述了索引的基本概念,索引的类型以及索引的基本使用方式。合理使用索引可以帮助我们提升查询效率,但索引也存在一些缺点,如单独占用空间,降低数据库的写操作性能等,所以我们在使用索引时需要权衡索引的利与弊。

在实际工作中,我们也要根据查询的业务逻辑来决定如何建立索引,牢记最左匹配原则,适当对语句进行改写以便于索引生效,也可以大大提升数据查询的性能。

好了,今天我们要讲的内容到这里就结束了,如果有什么疑问或者启发,欢迎大家在评论区进行留言。下一期我们会从索引背后的原理:B树和B+树的算法实现进行讲解,敬请期待!

2f2cc7acdb31ac4c7f6e5a46cc9307b6.png

您的点赞和在看是我创作的最大动力,感谢支持

4adc9577564f5db40df6542a01fae604.jpeg

f58d5f46aae1e057bebd358457ab4381.png

e15140963ecebd32663de35174e3d77e.png

公众号:wacky的碎碎念

知乎:wacky

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

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

相关文章

【ArcGIS微课1000例】0052:创建地理数据库注记(标准注记、要素关联注记、尺寸注记)

本文讲述创建地理数据库注记(标准注记、要素关联注记、尺寸注记)的方法。 文章目录 一、创建标准注记二、创建与要素关联的注记三、创建尺寸注记一、创建标准注记 标准注记不与地理数据库中的要素关联。标准注记的一个例子是,地图上标记某山脉的文字,没有特定的要索代表该…

Lambda表达式超详解

目录 背景 Lambda表达式的用法 函数式接口 Lambda表达式的基本使用 语法精简 变量捕获 匿名内部类 匿名内部类中的变量捕获 Lambda的变量捕获 Lambda表达式在类集中的使用 Collection接口 List接口 Map接口 总结 背景 Lambda表达式是Java SE 8中的一个重要的新特性.…

【ArcGIS微课1000例】0043:ArcGIS绘制国界线的3种方法

本文讲解ArcGIS绘制国界线的3种方法。 文章目录 1. 直接修改国界线符号2. 缓冲区工具3. 制图表达1. 直接修改国界线符号 直接修改国界线/省界线的符号。点击“线要素”出现符号选择器,点击【编辑符号】按钮,编辑成下面右图的形式。缺点:只能在边界一侧出现缓冲样式,如下面…

C# 获取系统已安装的.NET版本

本文经原作者授权以原创方式二次分享&#xff0c;欢迎转载、分享。原文作者&#xff1a;唐宋元明清原文地址&#xff1a; https://www.cnblogs.com/kybs0/p/16478587.htmlC# 获取系统已安装的.NET版本获取系统已安装的.NET版本&#xff0c;来确定当前应用可运行的环境。获取系…

.NET 6 Minimal API 的经验分享

Minimal API 是 .NET 6 提供的最新功能 &#xff0c; 对比传统的 ASP.NET Core Web API 方式更加直接 , 你可以用几行代码编写好 REST API 。 没有了祖传的 Startup.cs 和 Controller &#xff0c;通过简单的代码就可以完成 API 的开发。在第二阶段的 .NET 挑战赛中就以 .NET 6…

JavaWeb之Filter过滤器

原本计划这一篇来总结JSP&#xff0c;由于JSP的内容比较多&#xff0c;又想着晚上跑跑步减减肥&#xff0c;所以今天先介绍Filter以及它的使用举例&#xff0c;这样的话还有些时间可以锻炼锻炼。言归正传&#xff0c;过滤器从字面理解她的话有拦网、过滤的功能&#xff0c;可以…

【ArcGIS微课1000例】0054:尺寸注记的创建与编辑

尺寸注记要素是一种特殊类型的文本,用于显示地图上的长度或距离,可以创建各种形状的尺寸注记要素,如对齐、简单对齐、水平线状、垂直线状和旋转线状等。 文章目录 一、创建尺寸注记1. 直接创建尺寸注记要素2. 通过已有尺寸注记要素创建二、编辑尺寸注记1. 删除尺寸注记要素2…

利用python实现批量查询ip地址归属地址

今天需要查询nginx访问的客户端ip是否和调度一样&#xff01;先是用shell把文件中的ip截取出来&#xff1a; python脚本如下&#xff1a;&#xff08;哈哈&#xff0c;新手写的很草率&#xff09;#!/usr/bin/env#-- coding: utf-8 - import jsonimport urllibimport socketimpo…

基于.NetCore开发博客项目 StarBlog - (16) 一些新功能 (监控/统计/配置/初始化)

系列文章基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客&#xff1f;基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目基于.NetCore开发博客项目 StarBlog - (3) 模型设计基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入基于.N…

堪比JMeter的.Net压测工具 - Crank 入门篇

1. 前言 Crank 是.NET 团队用来运行基准测试的基准测试基础架构&#xff0c;包括&#xff08;但不限于&#xff09;来自TechEmpower Web 框架基准测试的场景,是2021年.NET Conf 大会上介绍的一项新的项目&#xff0c;其前身是Benchmarks。 Crank目标之一是为开发人员提供一种工…

【GlobalMapper精品教程】016:按照指定字段批量生成不同用地类型的矢量图层

Globalmapper中可以很方便的根据指定的字段,对矢量数据进行批量提取,生成不同类型的多个矢量数据,本文以土地利用现状数据为例,基于DLMC,提取出不同用地类型的矢量图层。 参考阅读:【ArcGIS遇上Python】ArcGIS Python按照指定字段批量筛选不同类型的图斑(以土地利用数据…

javascript闭包—围观大神如何解释闭包

闭包的概念已经出来很长时间了&#xff0c;网上资源一大把&#xff0c;本着拿来主意的方法来看看。 这一篇文章 学习Javascript闭包&#xff08;Closure&#xff09; 是大神阮一峰的博文&#xff0c;作者循序渐进&#xff0c;讲的很透彻。下面一一剖析。 1.变量的作用域 变量的…

.NET 20周年专访 - 张善友:.NET 技术是如何赋能并改变世界的

点击蓝字关注我们今年是 .NET 发布20周年&#xff0c;值此20周年之际&#xff0c;微软 Reactor 特别策划了 .NET 20周年系列主题专访。我们邀请了数位中国 .NET 领域的技术专家以及社区名人&#xff0c;来聊聊他们与 .NET 的情缘、认识 .NET 的契机、选择 .NET 的理由&#xff…

【ArcGIS错误异常100问】之005:ArcGIS字段计算器python中文编码问题解决

问题描述&#xff1a; 现因工作的需要&#xff0c;对照2017最新版&#xff1a;《土地利用现状分类》&#xff08;GBT 21010-2017&#xff09;&#xff0c;需根据DLMC对DLBM进行批量修改&#xff0c;如旱地是0103&#xff0c;其他林地是0307等&#xff0c;共计19种用地类型。 问…

【ArcGIS微课1000例】0055:根据图层创建自定义图例符号案例教程

在利用ArcGIS作图时,有时候需要根据线状或面状图层自己的矢量形状去创建图例项目符号,本文讲解根据图层创建自定义图例符号。 本实验使用的数据为配套案例数据包中的0055.rar中的水库数据。 文章目录 1. 添加“新建图例图面形状”工具2. 根据图层形状创建符号3. 绘制形状符号…

真魔法!图形化管理 Kafka 超轻量的自动化工具

Kafka Magic[1] 是一个用于处理 Apache Kafka 集群的 GUI 工具。它可以查找和显示消息、在 Topic 之间转换和移动消息、查看和更新模式、管理 Topic 以及自动化复杂任务。Kafka Magic 通过方便的用户界面促进 Topic 管理、QA 和集成测试。Kafka Magic Community Edition 可免费…

【FME实战教程】001:FME2020中文安装图文教程(附安装包下载)

文章目录1. 安装license2. 安装FME Desktop3. 安装中文语言4. FME软件下载地址1. 安装license 打开软件安装包中的fme-flexnet-win-x64.msi&#xff0c;如下图所示&#xff1a; 点击Next。 点击Next。 单击install。 点击finish&#xff0c;完成。 &#xff08;1&#xff09;修…

算法导论 第三部分——基本数据结构——第14章:数据结构的扩张

本章通过扩张红黑树构造出两种数据结构&#xff1a;动态顺序统计和区间树。 1、动态顺序统计&#xff1a;查找倒数第i小的数据 复杂度为 lg(n) 为什么是扩张红黑树而不是搜索二叉树或者二叉树&#xff1f; 相对于搜索二叉树&#xff0c;红黑树的平衡性更好&#xff0c;高度在l…

/hgfs下无共享文件夹?/mnt下没有hgfs文件夹?vmhgfs-fuse:找不到命令?

前言&#xff1a;最近在使用linux的过程中&#xff0c;需要在宿主操作系统与客户操作系统间建立共享文件夹&#xff0c;遇到了些许问题&#xff0c;在网上参考了许多文章与各种尝试后&#xff0c;现得以解决&#xff0c;分享如下。1、系统环境&#xff1a;宿主操作系统&#xf…