经验笔记:SQL调优
SQL调优经验笔记
引言
SQL调优是确保数据库系统高效运行的重要环节。通过对查询语句、数据库配置、硬件资源等方面进行优化,可以显著提升数据库性能,进而增强应用程序的整体表现。以下是基于常见调优手段和实践经验整理的一份经验笔记。
1. 查询语句优化
- 1.1 避免使用
SELECT *
只选择需要的列,减少不必要的数据传输。
示例:
-- 不推荐
SELECT * FROM users WHERE id = 1;-- 推荐
SELECT first_name, last_name, email FROM users WHERE id = 1;
- 1.2 用
UNION ALL
代替UNION
UNION ALL
不进行去重操作,执行速度更快。
示例:
-- 不推荐
(SELECT first_name, last_name FROM users WHERE city = 'New York')
UNION
(SELECT first_name, last_name FROM users WHERE city = 'Los Angeles');-- 推荐
(SELECT first_name, last_name FROM users WHERE city = 'New York')
UNION ALL
(SELECT first_name, last_name FROM users WHERE city = 'Los Angeles');
-
1.3 小表驱动大表
描述:在连接查询中,如果有一个小表和一个大表,应该优先使用小表来驱动大表,以减少处理的数据量。
不推荐:
SELECT * FROM orders o JOIN users u ON o.user_id = u.id WHERE u.status = 'active';
这个查询会先从
orders
表开始,然后对于每一个orders
表中的记录,都会去users
表中查找匹配的记录。如果orders
表很大,而符合条件的users
很少,那么这种查询效率不高。推荐:
SELECT * FROM orders o WHERE o.user_id IN (SELECT id FROM users WHERE status = 'active');
这个查询先从
users
表中找出所有状态为active
的用户ID,然后从orders
表中选择那些用户ID包含在这些活跃用户ID中的订单记录。这种方式减少了处理orders
表的数据量。 -
1.4 批量操作
批量插入或更新数据,减少请求次数,提高性能。
示例:-- 不推荐 INSERT INTO orders (order_id, product_id, quantity) VALUES (1, 1, 10); INSERT INTO orders (order_id, product_id, quantity) VALUES (2, 2, 20); INSERT INTO orders (order_id, product_id, quantity) VALUES (3, 3, 30);-- 推荐 INSERT INTO orders (order_id, product_id, quantity) VALUES (1, 1, 10), (2, 2, 20), (3, 3, 30);
-
1.5 多用
LIMIT
限制查询结果的数量,提高查询效率。
示例:-- 不推荐 SELECT * FROM orders ORDER BY order_date DESC;-- 推荐 SELECT * FROM orders ORDER BY order_date DESC LIMIT 10;
-
1.6 限制
IN
子句中的值
避免查询大量数据导致接口超时。
示例:-- 不推荐 SELECT * FROM categories WHERE id IN (1, 2, 3, ..., 10000);-- 推荐 SELECT * FROM categories WHERE id IN (1, 2, 3, ..., 100) LIMIT 500;
-
1.7 增量查询
通过条件限制,每次只查询部分数据,提高同步效率。
示例:-- 不推荐 SELECT * FROM users WHERE create_time > '2024-01-01';-- 推荐 SELECT * FROM users WHERE id > #{lastId} AND create_time >= #{lastCreateTime} LIMIT 100;
-
1.8 高效的分页
使用ID范围查询代替偏移量分页。
示例:-- 不推荐 SELECT * FROM users LIMIT 1000, 20;-- 推荐 SELECT * FROM users WHERE id > 1000000 LIMIT 20;
-
1.9 用连接查询代替子查询
描述:使用连接查询而不是子查询,以减少临时表的创建,提高查询效率。
不推荐:
SELECT * FROM orders WHERE user_id = (SELECT id FROM users WHERE status = 'active');
这里假设只有一个用户的
status
为active
。如果有多条记录符合条件,那么子查询将返回多行结果,可能导致内部错误或低效的处理。推荐:
SELECT o.* FROM orders o INNER JOIN users u ON o.user_id = u.id WHERE u.status = 'active';
这个查询通过连接两个表直接获取结果,减少了因子查询导致的临时表创建。
-
1.10 JOIN的表不宜过多
控制JOIN表的数量,避免复杂的索引选择。
示例:-- 不推荐 SELECT a.name, b.name, c.name FROM a INNER JOIN b ON a.id = b.a_id INNER JOIN c ON c.b_id = b.id;-- 推荐 SELECT a.name, b.name FROM a INNER JOIN b ON a.id = b.a_id;
-
1.11 JOIN时注意小表驱动大表
描述:使用INNER JOIN时,应让小表驱动大表;使用LEFT JOIN时,左边应为小表。
不推荐:
SELECT o.id, o.code, u.name FROM orders o LEFT JOIN users u ON o.user_id = u.id WHERE u.status = 'active';
这个查询使用了LEFT JOIN,意味着
orders
表中的每一行都会被处理,即使users
表中没有匹配的记录。如果orders
表很大,而users
表中符合条件的记录很少,这会导致很多空值的行。推荐:
SELECT o.id, o.code, u.name FROM orders o INNER JOIN users u ON o.user_id = u.id WHERE u.status = 'active';
这个查询只返回
orders
表中那些其user_id
在符合条件的users
表中的记录,这样可以减少处理的数据量。 -
1.12 控制索引的数量
合理控制索引数量,避免过多的索引导致性能消耗。
示例:-- 不推荐 CREATE INDEX idx_user_id ON orders (user_id); CREATE INDEX idx_order_date ON orders (order_date); CREATE INDEX idx_product_id ON orders (product_id);-- 推荐 CREATE INDEX idx_user_id_order_date ON orders (user_id, order_date);
-
1.13 选择合理的字段类型
根据数据特点选择合适的字段类型。
示例:-- 不推荐 ALTER TABLE orders ADD COLUMN order_code VARCHAR(20) NOT NULL;-- 推荐 ALTER TABLE orders ADD COLUMN order_code CHAR(10) NOT NULL;
-
1.14 提升
GROUP BY
的效率
在GROUP BY
前使用WHERE
条件过滤数据。
示例:-- 不推荐 SELECT user_id, COUNT(*) FROM orders GROUP BY user_id;-- 推荐 SELECT user_id, COUNT(*) FROM orders WHERE user_id <= 200 GROUP BY user_id;
-
1.15索引优化
描述:使用
EXPLAIN
命令来检查SQL查询是否有效地利用了索引。不推荐:
SELECT * FROM orders WHERE code = '002';
如果
code
列上没有索引,那么数据库将执行全表扫描,这是低效的。推荐:
EXPLAIN SELECT * FROM orders WHERE code = '002';
通过
EXPLAIN
命令,我们可以看到查询计划,并确认是否使用了索引。如果未使用索引,可能需要考虑添加适当的索引。
2. 数据库配置
-
2.1 调整缓存大小
根据系统可用内存调整数据库缓存大小,以提高数据访问速度。
示例:-- MySQL示例 SET GLOBAL innodb_buffer_pool_size = 1G;
-
2.2 内存管理
优化内存分配,确保足够的内存用于缓存经常访问的数据。
示例:-- PostgreSQL示例 ALTER SYSTEM SET shared_buffers = '128MB';
-
2.3 事务隔离级别
根据应用程序的需求调整事务隔离级别,以平衡并发性和一致性。
示例:-- MySQL示例 SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
-
2.4 日志和备份设置
优化日志记录和备份策略,以减少对性能的影响。
示例:-- MySQL示例 SET GLOBAL log_bin_trust_function_creators = 1;
3. 硬件和基础设施
-
3.1 扩展硬件资源
增加更多的CPU核心、内存或更快的磁盘(如SSD)以提升性能。
示例:- 升级服务器硬件
- 使用固态硬盘(SSD)
-
3.2 分布式架构
采用分片(Sharding)、复制(Replication)等技术分散负载。
示例:- 使用分片技术将数据分布在不同的物理服务器上
- 设置主从复制,提高读写分离的能力
-
3.3 负载均衡
使用负载均衡器来分发请求,减轻单个服务器的压力。
示例:- 配置Nginx或HAProxy作为负载均衡器
4. 应用程序层面
-
4.1 缓存机制
在应用程序层面上实现缓存机制,减少对数据库的直接访问。
示例:- 使用Redis或Memcached作为缓存层
-
4.2 异步处理
对于耗时的操作,可以采用异步处理的方式,如队列或消息传递系统。
示例:- 使用RabbitMQ或Kafka作为消息队列
-
4.3 数据模型优化
重新设计数据模型,减少冗余,提高数据的一致性和可维护性。
示例:- 规范化数据表结构
- 减少冗余字段
5. 持续监测
-
5.1 性能监控
使用性能监控工具持续监控数据库的运行状况,及时发现性能下降的情况。
示例:- 使用Prometheus和Grafana进行性能监控
-
5.2 日志分析
定期分析数据库日志,查找可能导致性能问题的模式。
示例:- 使用Logstash收集日志
- 使用Elasticsearch进行日志分析
-
5.3 定期审查
定期审查SQL查询和数据库设计,寻找潜在的优化机会。
示例:- 定期进行代码审查
- 使用性能分析工具检查查询效率
6. 教育和培训
-
6.1 团队技能提升
确保开发团队有足够的知识来编写高效的SQL查询,并了解数据库的最佳实践。
示例:- 组织内部培训课程
- 分享最新的SQL调优技巧
-
6.2 持续学习
鼓励团队成员跟踪最新的数据库技术和优化策略。
示例:- 参加技术会议
- 阅读技术博客和论文
7. 实施步骤
-
7.1 制定计划
根据监测到的问题制定具体的优化计划。
示例:- 列出需要优化的SQL查询
- 确定需要调整的数据库配置
-
7.2 小规模测试
在不影响生产环境的情况下,先在一个小规模的环境中测试优化措施。
示例:- 使用测试数据库进行实验
- 收集测试结果
-
7.3 逐步实施
一旦验证了优化措施的有效性,逐步将其应用于生产环境。
示例:- 先在非高峰时段部署
- 监控效果
-
7.4 效果评估
实施后,再次进行性能测试,评估优化措施的效果,并根据需要继续调整。
示例:- 使用性能监控工具
- 定期复查性能
结论
SQL调优是一个持续的过程,需要不断地监测、分析和调整。通过以上提到的方法,可以有效提升数据库性能,确保应用程序能够平稳运行。在实践中,还需要根据具体的数据库系统、业务需求和技术环境进行灵活调整。
相关文章:

经验笔记:SQL调优
SQL调优经验笔记 引言 SQL调优是确保数据库系统高效运行的重要环节。通过对查询语句、数据库配置、硬件资源等方面进行优化,可以显著提升数据库性能,进而增强应用程序的整体表现。以下是基于常见调优手段和实践经验整理的一份经验笔记。 1. 查询语句优…...

Selenium使用浏览器用户配置进行测试
本文主要介绍了如何在使用Selenium WebDriver进行自动化测试时,创建和使用自定义的Firefox配置文件。 什么是Firefox配置文件? Firefox会将用户的个人信息,如书签、密码和用户偏好设置存储在一个称为配置文件的文件集合中,这些文…...

virsh命令的使用
virsh 是一个用于管理虚拟机的命令行工具,它与 libvirt 服务配合使用,支持对虚拟机的创建、配置、启动、停止等操作。 1、列出虚拟机 列出正在运行的虚拟机: virsh list列出所有虚拟机(包括未启动的): …...

【来学Vue吧】创建一个Vue项目
🌟 嗨,我是命运之光! 🌍 2024,每日百字,记录时光,感谢有你一路同行。 🚀 携手启航,探索未知,激发潜能,每一步都意义非凡。 首先需要配置Vue环境…...

C#迭代器方法和yield用法
一.迭代器方法介绍 可使用foreach循环进行遍历的方法,称为迭代器方法。 迭代器方法使用yield return语句返回元素。 到达yield return语句时,会记住当前在代码中的位置。 下次调用迭代器函数时,将从该位置开始执行。换言之,如果…...

斗破C++编程入门系列之二十六:数组、指针和字符串:动态内存分配和释放(一星斗师)
斗破C目录: 斗破C编程入门系列之前言(斗之气三段) 斗破C编程入门系列之二:Qt的使用介绍(斗之气三段) 斗破C编程入门系列之三:数据结构(斗之气三段) 斗破C编程入门系列之…...

Servlet 和 Spring Boot 的请求处理流程区别和例子
当然可以为您绘制一个流程图,展示 Servlet 和 Spring Boot 的请求处理流程。这将帮助我们更直观地比较两者的工作方式。 #mermaid-svg-PgFEmecUmDhvxxtQ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-P…...

C++笔记之map的实用操作
C++笔记之map的实用操作 文章目录 C++笔记之map的实用操作1.初始化1.1.使用列表初始化1.2.使用 `insert` 方法1.3.使用 `emplace` 方法1.4.复制构造1.5.移动构造2.赋值2.1.列表赋值2.2.插入元素2.3.批量插入3.取值3.1.使用 `[]` 操作符3.2.使用 `at()` 方法3.3.检查键是否存在3…...

Lombok失效:报错 找不到符号 Springboot项目
错误原因,Springboot项目为Lombok提供了版本管理的支持,所以引入Lombok依赖的时候,无需手动指定版本,手动指定了可能会导致依赖冲突。 去掉手动指定的版本,问题解决...

Linux 基础命令-文件与目录操作
在 Linux 操作系统中,文件和目录是组织和管理数据的核心单元。作为一个命令行驱动的操作系统,Linux 提供了一系列强大且灵活的命令来操作文件和目录。掌握这些命令不仅是管理 Linux 系统的基础,也是高效使用 Linux 环境的关键。 一、文件与目…...

Delphi 12.1安卓APP开发中获取硬件信息及手机号
Demo与代码已上传到CSDN下载。 这里简单说一下代码内容,完整代码请自行下载,不清楚的欢迎留言交流。 前言 演示Demo使用了我自己开发的一个控件,TLayoutPro 《Delphi D10.3 LayoutsPro 控件简介 -避免输入焦点被虚拟键盘遮挡》请查看并下载控…...

STM32 - 笔记4
1 STM32 示波器 基于STM32的简易示波器项目(含代码)——HAL库_stm32简易示波器 基于STM32的简易示波器项目(含代码)——HAL库_stm32简易示波器_stm32示波器-CSDN博客 【强烈推荐】基于stm32的OLED各种显示实现(含动态图)_stm32oled以十六进制显示-CSDN博客 STM32示波器…...

【H2O2|全栈】更多关于HTML(1)HTML进阶(一)
目录 HTML进阶知识 前言 准备工作 标签的扩展(一) 本文中的标签在什么位置使用? title标签 meta标签 name viewport referrer http-equiv charset content link标签 实际案例 可视部分 代码分析 其他标签 base标签 styl…...

新160个crackme - 053-devilz KeyGen me#3
运行分析 解压出来4个文件运行程序发现要破解Name和Serial PE分析 32位,petite壳 手动脱壳 使用windows XP虚拟机OD打开程序按2下F8,发现ESP变红,根据ESP定律,在该地址右键 -> HW break下断点 继续按2下F9,来到灰色…...

ORA-12514
第一步,去这个地址,查查你的服务名是否存在 第二步,没查到就是你服务名写错了,查到了就退出我的解答...

MyBatis-PlusDruid数据源
MyBatis-Plus简介 MyBatis-Plus(简称MP)是一个MyBatis的增强工具,它在MyBatis的基础上进行了增强而不改变其原有的功能,旨在简化开发、提高效率。以下是对MyBatis-Plus的详细简介: 一、基本概述 定义:MyBat…...

C#中chart绘制曲线
官网资料:Chart 类 (System.Windows.Forms.DataVisualization.Charting) | Microsoft Learn 类的 Chart 两个重要属性是 Series 和 ChartAreas 属性,这两个属性都是集合属性。 Series集合属性存储Series对象,这些对象用于存储要显示的数据以…...

c++数据结构算法题讲解
那么从本期文章开始,会尽量带大家一起刷题 第一题 题目 关键词 思路 源代码 class MinStack { public: void push(int val) { _st.push(val); if(_minst.empty() || val < _minst.top()) { _minst.push(val); } } void pop() { if(_st.top() _minst.top()) {…...

间隙锁在其他数据库管理系统中的类似实现
间隙锁在其他数据库管理系统中的类似实现 一、引言 在 MySQL 中,间隙锁在可重复读事务隔离级别下起到了防止幻读的重要作用。那么在其他数据库管理系统中,是否也有类似的机制来实现类似的功能呢?了解其他数据库管理系统中与间隙锁类似的实现,可以帮助我们更好地理解不同数…...

OpenCV 与 YoloV3的结合使用:目标实时跟踪
目录 代码分析 1. YOLO 模型加载 2. 视频加载与初始化 3. 视频帧处理 4. 物体检测 5. 处理检测结果 6. 边界框和类别显示 7. 帧率(FPS)计算 8. 结果显示与退出 9. 资源释放 整体代码 效果展示 总结 代码分析 这段代码使用 YOLO(…...

Worse is Better
Worse is Better是UNIX的设计哲学,通俗来说,就是:保持接口与实现的简单性,比系统的任何其他属性,包括准确性、一致性和完整性,都来得更加重要 设计系统时,接口和实现的简单性是至关重要的。这种…...

Python Web 框架篇:Flask、Django、FastAPI介绍及其核心技术
Python Web 框架篇:Flask、Django、FastAPI介绍及其核心技术 目录 🐍 Flask Flask 核心概念(路由、视图函数、模板渲染)Flask Blueprint 模块化应用Flask 扩展(Flask-SQLAlchemy、Flask-WTF、Flask-Migrate 等&#…...

【Qt网络编程基础】Tcp服务器和客户端(只支持一对一)
目录 一、编写思路 1、服务器 总体思路 详细思路 1. 构造函数 (Widget::Widget) 2. 启动监听 (Widget::on_btn_start_clicked) 3. 停止监听 (Widget::on_btn_cease_clicked) 4. 发送消息 (Widget::on_btn_info_clicked) 5. 接收消息 (Widget::receive_message) 6. 处…...

平台开发到落地详解:从食堂采购系统源码到可视化供应链管理数据大屏
随着数字化转型的加速,越来越多的企业和组织开始重视供应链的智能化与可视化管理。在食堂采购领域,供应链管理的复杂性与日俱增,而传统的手工操作往往效率低下、容易出错。因此,开发食堂采购系统并结合可视化数据大屏的解决方案&a…...

静态内部类
目录 一、什么是静态内部类二、静态内部类的意义 一、什么是静态内部类 在 Java 中,静态内部类(也称为静态嵌套类)是定义在一个类内部的类,但它与外部类没有关联,即它不持有外部类的引用。静态内部类可以访问外部类的…...

Vue+SpringBoot+数据库整体开发流程 1
本篇文章通过springboot整合mybatis-plus去实现后端对数据库的增删改查,以及响应给前端的url,让前端获得数据。 目录 一、简单搭建一个Vue项目 检查node.js版本 使用vue-cli创建空项目 Vue-cli工程中每个文件夹和文件的用处 二、Mysql数据库 创建数…...

百度Apollo打通与ROS的通信,扩展自动驾驶系统生态
技术文档|打通与ROS的通信,扩展自动驾驶系统生态_Apollo开发者社区 (baidu.com)...

Web3 项目安全手册
现如今针对 Web3 项目的攻击手法层出不穷,且项目之间的交互也越发复杂,在各个项目之间的交互经常会引入新的安全问题,而大部分 Web3 项目研发团队普遍缺少的一线的安全攻防经验,并且在进行 Web3 项目研发的时候,重点关…...

AI边缘计算在安防领域的智能化革新:赋能安防系统的智能化升级
随着人工智能(AI)和边缘计算技术的快速发展,两者在安防视频领域的应用日益广泛,为传统安防系统带来了革命性的变革。AI边缘计算技术通过将AI算法和模型部署在边缘设备上,实现了数据处理和智能决策的即时响应࿰…...

vscode配置C/C++环境(保姆级详细教程)
一. 引言 VSCode,全称为Visual Studio Code,是一款由微软开发的免费、开源的轻量级代码编辑器,它支持多种编程语言和平台,并提供丰富的扩展功能,让开发者能够更高效地编写代码。 大家能来搜用如何在VSCode配置C/C环境…...