当前位置: 首页 > article >正文

sql的索引与性能优化相关

之前面试的时候,由于在简历上提到优化sql代码,老是会被问到sql索引和性能优化问题,用这个帖子学习记录一下。

1.为什么要用索引

-------------------------------------------------------------------------------------------------------------------

想象一下,你在一个超级大的图书馆里找一本书。图书馆有数百万本书,而这些书按类别和作者名字乱七八糟地堆放在各个角落。你需要找一本特定的书,比如《哈利·波特与魔法石》。如果没有任何排序规则,你就只能从最前面一排一排地看书,直到找到你要的书,这样的查找过程非常慢,对吧?而且,如果书很多,查找起来就像大海捞针一样困难。

现在,假设图书馆给每本书都加上了“书名索引”——它将每本书的书名按字母顺序排列成一张目录。这时,如果你想找《哈利·波特与魔法石》,你只需要翻看目录,迅速定位到“H”的位置,接着直接找到那本书,速度快得多了。

这个目录就像数据库中的索引

------------------------------------------------------------------------------------------------------------------

为什么用索引?

1. 提高查询效率:

没有索引的情况下,数据库就像你在没有书名索引的图书馆里找书一样。查询时,数据库需要全表扫描,逐行检查每条记录,像从头到尾翻看每本书一样。对于大表(比如数据量上百万、上千万的表),这种做法非常慢,尤其在复杂的查询时,效率低下。

举个例子:

假设我们有一个包含百万条数据的表:Customers 表,每条数据记录一个客户的姓名、联系方式等信息。现在,我们执行一个查询:

SELECT * FROM Customers WHERE CustomerName = 'John Doe';

如果没有索引,数据库就需要检查每一行数据,查找匹配的记录。这就像在没有索引的图书馆里,逐本翻书找《John Doe》的资料一样,效率极低。

2. 通过索引加速查询:

如果你为 CustomerName 列创建了索引,就像为图书馆建立了一个目录表(查找表),所有的客户名字按字母顺序排列。当你查询 CustomerName = 'John Doe' 时,数据库会直接跳到字母 "J" 的位置,迅速定位到包含 John Doe 的记录,而无需扫描整个表。

CREATE INDEX idx_customer_name ON Customers (CustomerName);

当执行以下查询时:

SELECT * FROM Customers WHERE CustomerName = 'John Doe';

数据库就像翻开目录快速定位到John Doe的位置,避免了逐行扫描所有数据,查询速度大大提高。

3. 避免全表扫描的影响:

没有索引时,查询变得非常低效,特别是对于大表。假设 Customers 表有上千万条记录,每次查询时都需要扫描整个表,执行的时间可能需要几秒钟甚至几分钟。而如果表有索引,这个过程就像使用目录快速定位书籍,数据库能在毫秒级时间内找到结果。

---------------------------------------------------------------------------------------------------------------------

2.sql索引原理和演化过程 

首先是二分树法查找

普通的二叉树的缺点:新的数据节点有可能一直插入同一边,甚至形成一个链表:

作为改进,平衡二叉树出现了。
 平衡二叉树的缺点是:数据量增大的话,这棵平衡二叉树就会变得很高,一次查询需要多次IO操作。

然后是B树:

B树相比于之前的二叉树,一个节点可以存储多个数据,并按序排列。而且B树也可以开超过2个的分叉,使得这棵树更加扁平化,也就需要更少的IO操作。(有序排列的树配合二分法)

B树也有一些缺点:1.查找性能不够稳定 2.不适合做范围查找

作为B树增强版,B+树出现了

可以看到只有最下面一层节点存储数据,之前上面的节点可以用来多存储指向其他节点的指针,中间节点可以分更多叉,整棵树变得更扁平,也减少IO次数。

最后再把叶子节点用指针连接起来,解决范围查询的问题。

--------------------------------------------------------------------------------------------------------------

3.索引与性能优化

之前说过了合理运用索引,能提高查找效率,下面是五个利用索引联系起性能优化的例子,利用EXPLAIN关键字来看select语句的性能(type)。

type 等级的顺序从高到低是:

  1. const(最优)
  2. eq_ref
  3. ref
  4. range
  5. index
  6. ALL(最差)

(1)对索引执行函数或计算会变成全表查找,即type=all降低效率。

可以看到type是all,最差的。 

 

可以进行以下修改,提高查找效率。

(2)联合索引,排序不影响效率。

(3)索引前后顺序,单独使用后索引是无效索引查询即type=all。

 

可以改一下复合索引顺序,col2放前面。

(4)模糊匹配,前面值确不确定影响是否是索引查询,即type=range/all,比如即ike语句的前导模糊查询不能使用索引。

 

(5) 查询条件增加,结果精确,但超出索引范围,会using where。即索引覆盖效率快于回表查询。

 

---------------------------------------------------------------------------------

4.外键相关

外键(Foreign Key)是数据库中的一种约束,用于确保表与表之间的参照完整性。它确保从表中的某个字段值必须在主表中有对应的有效记录。

外键的作用:

  1. 数据一致性:外键保证从表中的数据引用主表中存在的有效数据,防止无效或错误的数据被插入。
  2. 表间关系:通过外键,表与表之间建立关联,常见的一对多关系、父子关系等。
  3. 防止孤立数据:外键还可以设置级联操作,确保删除或更新主表记录时,从表的数据被适当处理。

外键的基本概念:

  • 主表:包含唯一标识(如主键)的表。
  • 从表:引用主表主键或唯一字段的表。

外键的约束:

  • 级联操作(CASCADE):删除或更新主表记录时,自动删除或更新从表相关的记录。
  • 限制删除(RESTRICT):如果主表中的记录被引用,拒绝删除主表记录。
  • 置空(SET NULL):删除或更新主表记录时,将从表中相关的外键字段置为 NULL。

相关文章:

sql的索引与性能优化相关

之前面试的时候,由于在简历上提到优化sql代码,老是会被问到sql索引和性能优化问题,用这个帖子学习记录一下。 1.为什么要用索引 ------------------------------------------------------------------------------------------------------…...

Snapshot Compressed Imaging:打破传统成像的新视界

在我们的日常生活中,拍照、拍视频已经成为记录生活的常规操作。无论是用手机捕捉美丽的风景,还是用相机拍摄珍贵的瞬间,传统的成像方式似乎已经满足了我们大部分的需求。但你是否想过,在某些特殊的场景下,传统成像技术可能会遇到一些难题,而一种名为 Snapshot Compressed…...

git 命令 设置别名

在 Git 中,你可以通过配置别名来简化常用的命令。这样,你可以使用更短或更易记的命令来完成相同的操作。要设置 Git 命令的别名,你可以使用 git config 命令。 全局设置 如果你想为所有 Git 仓库设置别名,可以使用 --global 选项…...

在Spark中如何配置Executor内存以优化性能

在Spark中,配置Executor内存以优化性能是一个关键步骤。以下是一些具体的配置方法和建议: 一、Executor内存配置参数 在Spark中,Executor的内存配置主要通过以下几个参数进行: --executor-memory 或 spark.executor.memory&…...

Go语言--语法基础2--下载安装

2、下载安装 1、下载源码包: go1.18.4.linux-amd64.tar.gz。 官方地址:https://golang.google.cn/dl/ 云盘地址:链接: https://pan.baidu.com/s/1N2jrRHaPibvmmNFep3VYag 提 取码: zkc3 2、将下载的源码包解压…...

碰撞检测 | 图解凸多边形分离轴定理(附ROS C++可视化)

目录 0 专栏介绍1 凸多边形碰撞检测2 多边形判凸算法3 分离轴定理(SAT)4 算法仿真与可视化4.1 核心算法4.2 仿真实验 0 专栏介绍 🔥课设、毕设、创新竞赛必备!🔥本专栏涉及更高阶的运动规划算法轨迹优化实战,包括:曲线…...

计算机网络真题练习(高软29)

系列文章目录 计算机网络阶段练习 文章目录 系列文章目录前言一、真题练习总结 前言 计算机网络的阶段练习题,带解析答案。 一、真题练习 总结 就是高软笔记,大佬请略过!...

DPVS-1:编译安装DPVS (ubuntu22.04)

操作系统 rootubuntu22:~# lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy rootubuntu22:~# 前置软件准备 apt install git apt install meson apt install gcc ap…...

将 SELinux 永久设置为 Permissive

要将 SELinux 永久设置为 Permissive 模式,可以按照以下步骤操作: 1. 检查当前 SELinux 状态 首先,确认当前 SELinux 的状态: sestatus输出示例: SELinux status: enabled SELinuxfs mount: …...

EasyRTC:全平台支持与自研算法驱动的智能音视频通讯解决方案

在智能硬件的浪潮中,设备之间的互联互通已成为提升用户体验的核心需求。无论是智能家居、智能办公,还是工业物联网,高效的音视频通讯和交互能力是实现智能化的关键。然而,传统音视频解决方案往往面临平台兼容性差、交互体验不佳以…...

Elasticsearch 自动补全搜索 - autocomplete

作者:来自 Elastic Amit Khandelwal 探索处理自动完成的不同方法,从基础到高级,包括输入时搜索、查询时间、完成建议器和索引时间。 在本文中,我们将介绍如何避免严重的性能错误、Elasticsearch 默认解决方案为何不适用以及重要的…...

快速入门Springboot+vue——MybatisPlus多表查询及分页查询

学习自哔哩哔哩上的“刘老师教编程”,具体学习的网站为:7.MybatisPlus多表查询及分页查询_哔哩哔哩_bilibili,以下是看课后做的笔记,仅供参考。 多表查询 多表查询[Mybatis中的]:实现复杂关系映射,可以使…...

工程师 - VSCode的AI编码插件介绍: MarsCode

豆包 MarsCode MarsCode AI: Coding Assistant Code and Innovate Faster with AI 豆包 MarsCode - 编程助手 安装完成并使能后,会在下方状态栏上显示MarsCode AI。 安装完并重启VSCode后,要使用这个插件,需要注册一下账号。然后授权VSCod…...

VOS3000线路对接、路由配置与路由分析操作教程

一、VOS3000简介 VOS3000是一款常用的VoIP运营平台,支持多种线路对接和路由配置,适合新手快速上手。本教程将带你了解如何对接线路、配置路由以及进行路由分析。 二、线路对接 准备工作 获取线路信息:从供应商处获取线路的IP地址、端口、用…...

学习Linux准备2

使用win10系统带的wsl配置ubuntu系统,通过wsl功能我们可以更简单更轻松的获得Linux系统环境。 首先开启Windows自带的wsl功能 打开控制面板,选中启用或关闭Windows功能 这里我们点击进入 将上图红√点击上,点击确定,然后重新启动…...

Java IO 和 NIO 的基本概念和 API

一、 Java IO (Blocking IO) 基本概念: Java IO 是 Java 平台提供的用于进行输入和输出操作的 API。Java IO 基于 流 (Stream) 的模型,数据像水流一样从一个地方流向另一个地方。Java IO 主要是 阻塞式 I/O (Blocking I/O),即线程在执行 I/O …...

【数据结构】快指针和慢指针

一、 给你单链表的头结点 head ,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。 要求:只遍历一遍链表 可以使用快慢指针:fast 一次走两步,slow 一次走一步。当 fast NULL(偶数个结点)或…...

四、综合案例(Unity2D)

一、2D渲染 1、2D相机基本设置 上面是透视,下面是正交 2、图片资源 在Unity中,常规图片导入之后,一般不在Unity中直接使用,而是转为精灵图Sprite 将图片更改为即可使用Unity内置的图片切割功能 无论精灵图片是单个的还是多个的…...

全面汇总windows进程通信(三)

在Windows操作系统下,实现进程间通信(IPC, Inter-Process Communication)有几种常见的方法,包括使用管道(Pipe)、共享内存(Shared Memory)、消息队列(Message Queue)、命名管道(Named Pipe)、套接字(Socket)等。本文介绍如下几种: RPC(远程过程调用,Remote Pr…...

Caffeine:高性能的Java本地缓存库

文章目录 引言什么是Caffeine?Caffeine的主要特点Caffeine的使用方法Caffeine与Google Guava Cache的对比Caffeine与Ehcache的对比总结 引言 在现代软件开发中,缓存是提高应用性能的重要手段之一。通过缓存,可以减少对数据库或其他外部系统的…...

Codes 开源免费研发项目管理平台 2025年第一个大版本3.0.0 版本发布及创新的轻IPD实现

Codes 简介 Codes 是国内首款重新定义 SaaS 模式的开源项目管理平台,支持云端认证、本地部署、全部功能开放,并且对 30 人以下团队免费。它通过创新的方式简化研发协同工作,使敏捷开发更易于实施。并提供低成本的敏捷开发解决方案&#xff0…...

flowable 全生命周期涉及到的api及mysql表

要了解Flowable从流程创建到审批过程中涉及的API和MySQL表。之前对工作流引擎有一些基础了解,但具体到Flowable的细节可能不太熟悉。需要先回忆一下Flowable的基本概念,比如流程定义、流程实例、任务、执行实例等,然后逐步思考每个步骤会用到…...

Golang | 每日一练 (3)

💢欢迎来到张胤尘的技术站 💥技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 Golang | 每日一练 (3)题目参考答案map 实现原理hmapb…...

【java】类声明的两种形式

在 Java 中,类的声明有两种形式: public class Test class Test 它们的区别主要在于访问权限和文件名的要求。下面我会详细解释这两种形式的区别。 1. public class Test 访问权限: public 表示这个类是公共的,可以被其他包&am…...

VSCode 中设置 Git 忽略仅因时间戳修改导致的文件变更【使用deepseek生成的一篇文章】

在 VSCode 中设置 Git 忽略仅因时间戳修改导致的文件变更&#xff0c;可通过以下步骤实现&#xff1a; 确认是否为纯时间戳修改 首先确认文件的修改是否仅涉及时间戳&#xff0c;使用终端运行&#xff1a; git diff -- <file>若输出为空但 Git 仍提示修改&#xff0c;可…...

Docker入门及基本概念

让我们从最基础的概念开始逐步理解。假设你已经准备好了docker 环境。 第一步&#xff0c;让我们先通过实际操作来看看当前系统中的镜像(images)和容器(containers)状态&#xff1a; docker images # 查看所有镜像 docker ps -a # 查看所有容器&#xff08;包括未运行…...

java八股文-消息队列

一、MQ基础篇 1. 什么是消息队列&#xff1f; 消息队列&#xff08;MQ&#xff09;是分布式系统中实现异步通信的中间件&#xff0c;解耦生产者和消费者。 2. 使用场景有哪些&#xff1f; 异步处理&#xff08;如注册后发送邮件&#xff09;系统解耦&#xff08;不同服务通过…...

设备唯一ID获取,支持安卓/iOS/鸿蒙Next(uni-device-id)UTS插件

设备唯一ID获取 支持安卓/iOS/鸿蒙(uni-device-id)UTS插件 介绍 获取设备唯一ID、设备唯一标识&#xff0c;支持安卓&#xff08;AndroidId/OAID/IMEI/MEID/MacAddress/Serial/UUID/设备基础信息&#xff09;,iOS&#xff08;Identifier/UUID&#xff09;&#xff0c;鸿蒙&am…...

基于Springboot医院预约挂号小程序系统【附源码】

基于Springboot医院预约挂号小程序系统 效果如下&#xff1a; 小程序主页面 帖子页面 医生账号页面 留言内容页面 管理员主页面 用户管理页面 我的挂号页面 医生管理页面 研究背景 随着信息技术的飞速发展和互联网医疗的兴起&#xff0c;传统的医疗服务模式正面临着深刻的变…...

微信小程序 - 页面跳转(wx.navigateTo、wx.redirectTo、wx.switchTab、wx.reLaunch)

API 跳转 1、wx.navigateTo &#xff08;1&#xff09;基本介绍 功能&#xff1a;保留当前页面&#xff0c;跳转到应用内的某个页面&#xff0c;使用该方法跳转后可以通过返回按钮返回到原页面 使用场景&#xff1a;适用于需要保留当前页面状态&#xff0c;后续还需返回的情…...