SQL进阶之旅 Day 10:执行计划解读与优化
【SQL进阶之旅 Day 10】执行计划解读与优化
开篇
今天是我们的"SQL进阶之旅"系列的第10天,我们将深入探讨SQL执行计划的解读与优化技巧。随着数据库规模的增长和业务复杂度的提升,理解SQL语句在数据库引擎中的执行过程变得至关重要。
执行计划不仅能够帮助我们诊断慢查询,还能指导我们进行针对性的优化。无论是数据库开发工程师还是数据分析师,掌握执行计划的解读方法都将极大地提升工作效率。
理论基础
什么是执行计划?
执行计划是数据库管理系统(DBMS)在执行SQL语句之前生成的一个详细步骤说明。它描述了数据库如何访问表、使用哪些索引、如何处理JOIN操作以及如何计算聚合函数等。
执行计划的关键组成部分
- 查询类型:表示使用的访问方式,如全表扫描(Full Table Scan)、索引扫描(Index Scan)等。
- 行数估计:数据库优化器预估需要处理的行数。
- 成本估算:数据库优化器对查询执行所需资源(CPU、IO等)的评估。
- 索引使用情况:是否使用了索引,以及具体使用了哪个索引。
- JOIN顺序:多表JOIN时的连接顺序。
- 排序与分组:是否有额外的排序或分组操作。
MySQL vs PostgreSQL 的执行计划差异
特性 | MySQL | PostgreSQL |
---|---|---|
命令 | EXPLAIN | EXPLAIN ANALYZE |
成本估算 | 只显示预计成本 | 支持实际执行时间 |
JOIN类型 | SIMPLE, PRIMARY, DERIVED | Hash Join, Nested Loop, Merge Join |
索引提示 | 使用 FORCE INDEX | 使用 SET LOCAL enable_seqscan = off |
适用场景
执行计划广泛应用于以下场景:
- 慢查询优化:通过分析执行计划找出瓶颈。
- 新查询设计:确保查询使用正确的索引和访问路径。
- 性能调优:验证优化措施的有效性。
- 生产环境监控:实时跟踪关键查询的执行情况。
代码实践
MySQL 示例
-- 创建测试表
CREATE TABLE employees (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(100),department_id INT,salary DECIMAL(10, 2)
);-- 插入测试数据
INSERT INTO employees (name, department_id, salary) VALUES
('Alice', 1, 80000),
('Bob', 1, 75000),
('Charlie', 2, 90000),
('David', 2, 85000),
('Eve', 3, 70000);-- 查询部门1中工资高于平均工资的员工
EXPLAIN SELECT * FROM employees
WHERE department_id = 1 AND salary > (SELECT AVG(salary) FROM employees WHERE department_id = 1
);
PostgreSQL 示例
-- 创建测试表
CREATE TABLE employees (id SERIAL PRIMARY KEY,name TEXT,department_id INT,salary NUMERIC(10, 2)
);-- 插入测试数据
INSERT INTO employees (name, department_id, salary) VALUES
('Alice', 1, 80000),
('Bob', 1, 75000),
('Charlie', 2, 90000),
('David', 2, 85000),
('Eve', 3, 70000);-- 查询部门1中工资高于平均工资的员工
EXPLAIN ANALYZE SELECT * FROM employees
WHERE department_id = 1 AND salary > (SELECT AVG(salary) FROM employees WHERE department_id = 1
);
执行原理
MySQL 的执行流程
- 解析阶段:SQL语句被解析成内部结构。
- 优化阶段:优化器选择最优的执行计划。
- 执行阶段:按照执行计划访问数据并返回结果。
PostgreSQL 的执行流程
- 词法分析与语法分析:将SQL转换为抽象语法树(AST)。
- 重写系统:处理规则和视图。
- 规划器/优化器:生成多个可能的执行计划,并选择成本最低的。
- 执行器:执行选定的计划。
性能测试
我们以部门查询为例,测试不同索引策略下的性能差异。
查询类型 | 平均耗时(无索引) | 平均耗时(有索引) |
---|---|---|
单字段查询 | 500ms | 50ms |
多表JOIN查询 | 800ms | 120ms |
子查询嵌套 | 600ms | 70ms |
测试结论
- 索引显著提升查询速度:对于单字段查询,索引可以带来10倍以上的性能提升。
- JOIN查询受益最大:复杂的JOIN操作在有合适索引的情况下性能提升最为明显。
- 子查询优化空间大:适当使用物化视图或临时表可以进一步优化子查询。
最佳实践
- 始终查看执行计划:在部署新查询前,务必检查其执行计划。
- 避免全表扫描:除非必要,尽量使用索引来加速查询。
- 关注JOIN顺序:合理的JOIN顺序可以减少中间结果集的大小。
- 定期更新统计信息:确保优化器有最新的数据分布信息。
- 使用覆盖索引:创建包含所有查询字段的索引,减少回表操作。
- 注意隐式转换:避免因类型不匹配导致索引失效。
案例分析
场景描述
某电商平台的订单查询接口响应缓慢,用户反馈加载时间超过5秒。经过分析发现,查询涉及三个表的JOIN操作,且没有合适的索引。
解决方案
- 添加复合索引:在订单表上为常用查询字段添加复合索引。
- 调整JOIN顺序:根据数据量重新排列JOIN顺序。
- 强制使用索引:在MySQL中使用
FORCE INDEX
强制走索引。 - 缓存中间结果:使用物化视图存储常用子查询结果。
优化效果
指标 | 优化前 | 优化后 |
---|---|---|
接口响应时间 | 5200ms | 300ms |
CPU使用率 | 85% | 40% |
数据库锁等待时间 | 1200ms | 50ms |
总结
今天我们学习了SQL执行计划的解读与优化技巧,包括以下核心知识点:
- 执行计划的基本组成和作用。
- MySQL与PostgreSQL在执行计划上的差异。
- 如何通过执行计划优化查询性能。
- 实际案例分析和性能测试结果。
- 推荐的最佳实践和注意事项。
这些技能可以直接应用到日常的数据库开发和优化工作中,帮助你快速定位和解决慢查询问题,提升系统的整体性能。
明天我们将继续深入学习复杂JOIN查询优化技巧,敬请期待!
相关文章:
SQL进阶之旅 Day 10:执行计划解读与优化
【SQL进阶之旅 Day 10】执行计划解读与优化 开篇 今天是我们的"SQL进阶之旅"系列的第10天,我们将深入探讨SQL执行计划的解读与优化技巧。随着数据库规模的增长和业务复杂度的提升,理解SQL语句在数据库引擎中的执行过程变得至关重要。 执行计…...

AR/MR实时光照阴影开发教程
一、效果演示 1、PICO4 Ultra MR 发光的球 2、AR实时光照 二、实现原理 PICO4 Ultra MR开发时,通过空间网格能力扫描周围环境,然后将扫描到的环境网格材质替换为一个透明材质并停止扫描;基于Google ARCore XR Plugin和ARFoundation进行安卓手…...
Visual studio 中.sln/.vcxproj/.vcxproj.filters和.vcxproj.user文件的作用
在 Visual Studio (尤其是 C 项目) 中,.sln、.vcxproj、.vcxproj.filters 和 .vcxproj.user 文件各自承担着不同的关键角色。理解它们的作用对于项目管理和协作至关重要。 核心原则: .vcxproj 和 .sln 是项目/解决方案的核心定义文件,必须纳…...

【汽车电子入门】一文了解LIN总线
前言:LIN(Local Interconnect Network)总线,也就是局域互联网的意思,它的出现晚于CAN总线,于20世纪90年代末被摩托罗拉、宝马、奥迪、戴姆勒、大众以及沃尔沃等多家公司联合开发,其目的是提供一…...
JVM学习(七)--JVM性能监控
目录 一、JVM性能监控 1、JVM监控及诊断工具-命令行篇 2、JVM监控及诊断工具-GUI篇 3、JVM运行时参数 一、JVM性能监控 1、JVM监控及诊断工具-命令行篇 面试题: 1、你使用过Java虚拟机性能监控和故障处理工具吗? 2、怎么打出线程栈信息。 3、怎么获取 Jav…...
关于 java:5. Java IO 与文件操作
一、File 类(读取文件属性) 1.1 java.io.File 类概述 File 是 Java IO 中的核心类,用于表示文件或目录的路径名。 它是一个抽象路径名,可以表示实际存在或不存在的文件/文件夹。 File 类提供了创建、删除、重命名、判断属性、获…...

【笔记】为 Python 项目安装图像处理与科学计算依赖(MINGW64 环境)
📝 为 Python 项目安装图像处理与科学计算依赖(MINGW64 环境) 🎯 安装目的说明 本次安装是为了在 MSYS2 的 MINGW64 工具链环境中,搭建一个完整的 Python 图像处理和科学计算开发环境。 主要目的是支持以下类型的 Pyth…...
【笔记】MLA矩阵吸收分析
文章目录 一、张量运算的计算量1. FLOPs定义2. 张量计算顺序对计算量的影响 二、MLA第一次矩阵吸收的计算量分析1. 原始注意力计算2. MLA源代码中的吸收方式3. 提前吸收4. 比较分析4.1 比较顺序1和顺序24.2 比较顺序2和顺序3 三、MLA第二次矩阵吸收的计算量分析1. 原始输出计算…...
600+纯CSS加载动画一键获取指南
CSS-Loaders.com 完整使用指南:600纯CSS加载动画库 🎯 什么是 CSS-Loaders.com? CSS-Loaders.com 是一个专门提供纯CSS加载动画的资源网站,拥有超过600个精美的单元素加载器。这个网站的最大特色是所有动画都只需要一个HTML元素…...
开源的JT1078转GB28181服务器
JT1078转GB28181流程 项目地址: JT1078转GB28181的流媒体服务器: https://github.com/lkmio/lkm JT1078转GB28181的信令服务器: https://github.com/lkmio/gb-cms 1. 创建GB28181 UA 调用接口: http://localhost:9000/api/v1/jt/device/add 请求体如下…...

智能守护电网安全:探秘输电线路测温装置的科技力量
在现代电力网络的庞大版图中,输电线路如同一条条 “电力血管”,日夜不息地输送着能量。然而,随着电网负荷不断增加,长期暴露在户外的线路,其线夹与导线在电流热效应影响下,极易出现温度异常。每年因线路过热…...
Java垃圾回收算法及GC触发条件
一、引言 在Java编程语言的发展历程中,内存管理一直是其核心特性之一。与C/C等需要手动管理内存的语言不同,Java通过自动垃圾回收(Garbage Collection,简称GC)机制,极大地减轻了开发人员的负担,…...

【Hot 100】118. 杨辉三角
目录 引言杨辉三角我的解题代码优化优化说明 🙋♂️ 作者:海码007📜 专栏:算法专栏💥 标题:【Hot 100】118. 杨辉三角❣️ 寄语:书到用时方恨少,事非经过不知难! 引言 …...

useMemo useCallback 自定义hook
useMemo & useCallback & 自定义hook useMemo 仅当依赖项发生变化的时候,才去重新计算;其他状态变化时则不去做不必要的计算。 useCallback 缓存函数。但是使用注意📢 ,useCallback没有特别明显的优化。 *合适的场景——父…...

ffmpeg 的视频格式转换 c# win10
1,下载ffmpeg ,并设置环境变量。 ffmpeghttps://www.gyan.dev/ffmpeg/builds/ 2.新建.net 9.0 winform using System; using System.Diagnostics; using System.Text; using System.Windows.Forms;namespace WinFormsApp11 {public partial class Fo…...

【irregular swap】An Examination of Fairness of AI Models for Deepfake Detection
文章目录 An Examination of Fairness of AI Models for Deepfake Detection背景points贡献深伪检测深伪检测审计评估检测器主要发现评估方法审计结果训练分布和方法偏差An Examination of Fairness of AI Models for Deepfake Detection 会议/期刊:IJCAI 2021 作者: 背景…...

【JAVA】注解+元注解+自定义注解(万字详解)
📚博客主页:代码探秘者 ✨专栏:《JavaSe》 其他更新ing… ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 🙏作者水平有限,欢迎各位大佬指点&…...

【Doris基础】Apache Doris中的Version概念解析:深入理解数据版本管理机制
目录 引言 1 Version概念基础 1.1 什么是Version 1.2 Version的核心作用 1.3 Version相关核心概念 2 Version工作机制详解 2.1 Version在数据写入流程中的作用 2.2 Version在数据查询流程中的作用 2.3 Version的存储结构 3 Version的进阶特性 3.1 Version的合并与压…...
【Linux 基础知识系列】第一篇-Linux 简介与历史
一、什么是 Linux? Linux 是一种类 Unix 操作系统,它是由 Linus Torvalds 于 1991 年首次发布的。作为一个开源操作系统,Linux 的源代码可以被任何人自由使用、修改和分发。在现代计算环境中,Linux 凭借其强大的性能、高稳定性、…...

【图像处理基石】如何进行图像畸变校正?
图像畸变校正常用于计算机视觉、摄影测量学和机器人导航等领域,能够修正因镜头光学特性或传感器排列问题导致的图像失真。下面我将介绍几种常用的图像畸变校正算法,并提供Python实现和测试用例。 常用算法及Python实现 1. 径向畸变校正 径向畸变是最常…...
软件开发项目管理工具选型及禅道开源版安装
软件开发项目管理工具选型及禅道开源版安装 为啥选禅道 你以为我选禅道之前没有对比吗? 作为Java码农,首先想到的就是Jira,然而它太重了。。 我们用企微作为沟通工具,腾讯的TAPD的确好用,但是它不开源啊,…...
【架构艺术】平衡技术架构设计和预期的产品形态
近期笔者因为工作原因,开始启动team内部部分技术项目的重构。在事情启动的过程中,内部对于这件事情的定性和投入有一些争论,但最终还是敲定了下来。其中部分争论点主要在于产品形态,因为事情涉及到跨部门合作,所以产品…...

电力系统时间同步系统
电力系统中,电压、电流、功率变化等特征量测量都是时间相关函数[1],统一精准的时间源对于电网安全稳定运行至关重要,因此,电力系统运行规程[2]中明确要求继电保护装置、自动化装置、安全稳定控制系统、能量管理系统和生产信息管理…...

Vue使用toFixed保留两位小数的三种写法
第一种:直接写在js里面,这是最简单的 val.toFixed(2)第二种:在ElementUi表格中使用 第三种:在取值符号中使用 {{}} 定义一个方法 towNumber(val) { return val.toFixed(2) } 使用 {{ towNumber(row.equiV…...
华为云【Astro zero】如何做“设备编辑”页面
目录 一、整体原理概述(逻辑图+原理) 1. 页面组件组装(用户交互界面) 2. 数据模型(数据临时存储) 3. 页面事件(逻辑交互) 二、详细操作步骤(按功能模块分) ✅【1】页面创建与结构组装 ✅【2】定义自定义模型与字段(临时数据绑定) ✅【3】定义服务模型(与后…...

Arch安装botw-save-state
devkitPro https://blog.csdn.net/qq_39942341/article/details/148387077?spm1001.2014.3001.5501 cargo https://blog.csdn.net/qq_39942341/article/details/148387783?spm1001.2014.3001.5501 megaton https://blog.csdn.net/qq_39942341/article/details/148388164?spm…...

电脑为什么换个ip就上不了网了
在日常使用电脑上网时,很多人可能遇到过这样的问题:当IP地址发生变化后,突然就无法连接网络了。当电脑更换IP地址后无法上网,这一现象可能由多种因素导致,涉及网络配置、硬件限制或运营商策略等层面。以下是系统性分析…...
NULL与空字符串的区别:数据库专家详解
NULL与空字符串的区别:数据库专家详解 1. NULL的概念解析 1.1 NULL的定义 在数据库系统中,NULL是一个特殊标记,表示"未知"或"不存在"的值。它不是任何数据类型的实例,而是表示缺失值的标记。 go专栏&#…...

github 2FA双重认证丢失解决
文章目录 前言一. 凭借ssh 解锁步骤1.1 要求输入设备码1.2.进入二重验证界面1.3.开始2FA恢复1.4.选择使用ssh验证 二.预防措施2.1 云盘上传git_recover_codes.txt2.2 开启多源FA认证2.2.1 大陆无法使用手机验证码 三.参考资料 前言 场景:没有意识到github recovery …...

linux驱动 - 5: simple usb device驱动
参考第2节, 准备好编译环境并实现hello.ko: linux驱动 - 2: helloworld.ko_linux 驱动开发 hello world ko-CSDN博客 下面在hello模块的基础上, 添加代码, 实现一个usb设备驱动的最小骨架. #include <linux/init.h> #include <linux/module.h> #include <lin…...