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

前言

上一次,我们从优化子查询的角度,讲解了一些简单的数据库性能优化方面的知识。通过优化子查询的顺序,包括合理使用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,一经查实,立即删除!

相关文章

题目1023:EXCEL排序---------Case后面的是count,不是C

#include<stdio.h> #include<algorithm> #include<cstring> using namespace std;struct student {char num[10];char name[10];int grade; }s[100002]; int cmp1(student s1,student s2)//case 1 按照学号递增 {return strcmp(s1.num,s2.num)<0; } int…

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

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

Lambda表达式超详解

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

用十条命令在一分钟内检查Linux服务器性能

这种干活必须要和大家分享的啊。 如果你的Linux服务器突然负载暴增&#xff0c;告警短信快发爆你的手机&#xff0c;如何在最短时间内找出Linux性能问题所在&#xff1f;来看Netflix性能工程团队的这篇博文&#xff0c;看它们通过十条命令在一分钟内对机器性能问题进行诊断。 概…

[javaEE] JDBC快速入门

JDBC&#xff1a;Java Data Base Connectivity java数据库连接 1.组成JDBC的两个包&#xff1a;主要是接口 java.sql javax.sql 2.相应JDBC的数据库实现 在tomcat的目录下面添加mysql-connector-java-5.0.8-bin.jar这个数据库驱动包 package com.tsh.web;import java.io.IOExce…

【ArcGIS微课1000例】0053:注记(水平、沿直线、跟随要素、牵引线、弯曲注记)的创建与编辑

文章目录 一、创建注记1.创建注记要素类2. 水平注记3. 沿直线4. 随沿要素5. 沿引线6. 弯曲二、修改注记1. 复制粘贴2. 移动注记3. 旋转注记4. 删除注记5. 堆叠和取消堆叠6. 向注记添加引线7. 将注记转换为多部分8. 编辑关联要素的注记一、创建注记 注记的创建方法参考:【ArcG…

定制.NET 6.0的依赖注入

本章是《定制ASP NET 6.0框架系列文章》的第三篇。在本章&#xff0c;我们将学习ASP.NET Core的依赖项注入&#xff08;DI&#xff09;以及如何自定义它。我们将讨论以下主题&#xff1a;使用不同的DI容器探索ConfigureServices方法使用其他的ServiceProviderScrutor简介技术准…

50 个 Redis 必备知识:基础知识,架构、调优和监控知识及难点解决

本文包括&#xff1a;30 个 Redis 基础知识&#xff1b;10个 Redis 架构和运维必懂的知识&#xff1b;Redis 调优、监控知识和10个具体应用难点。 本篇文档已整理成pdf文档&#xff0c;需要的同学文末自取 30 个 Redis 基础知识 1、Redis支持哪几种数据类型&#xff1f; Str…

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

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

javascript杂记

菜鸟教程   http://www.runoob.com/js/js-tutorial.html 响应键盘事件  https://www.cnblogs.com/shihaiming/p/6210655.html 窗口变化  http://www.jb51.net/article/124581.htm div定位1  http://www.divcss5.com/shili/s587.shtml   div定位2  https://www.cnbl…

没有暑假的Ada 要好好努力咯 C#继续

嗷嗷嗷啊啊啊啊啊转载于:https://www.cnblogs.com/AdaLoong/p/5645720.html

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…

Cobbler部署之FAQ处理

Cobbler报错处理 通过cobbler check检查出现的报错 红色标注为报错关键信息 9.1 报错一 # cobbler check httpd does not appear to be running and proxying cobbler, or SELinux is in the way. Original traceback: Traceback (most recent call last): File "/usr…

基于.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目标之一是为开发人员提供一种工…