问:SQL优化,七条实践总结?
SQL语句优化是数据库性能调优的重要部分,通过合理的优化可以显著提升查询速度和系统性能。文章总结几种常见SQL语句优化方法。
1. 优化Where子句的顺序
原则:表之间的连接条件应写在其他Where条件之前,能够过滤掉最大数量记录的条件应优先写。
解释:数据库在执行查询时,会按照Where子句中的条件顺序进行过滤。如果最先执行的是最能缩小结果集的条件,那么后续的处理量将会大大减少,从而提高查询效率。
示例:
-- 不优化的写法
SELECT *
FROM orders o
WHERE o.order_date > '2023-01-01' AND o.customer_id = c.id AND c.region = 'North';-- 优化的写法
SELECT *
FROM orders o
JOIN customers c ON o.customer_id = c.id
WHERE c.region = 'North'AND o.order_date > '2023-01-01';
在优化的写法中,首先通过JOIN
条件连接orders
和customers
表,然后通过最能缩小结果集的条件c.region = 'North'
进行过滤,最后才是其他条件。
2. 用EXISTS替代IN、用NOT EXISTS替代NOT IN
原则:在处理子查询时,使用EXISTS通常比IN更高效,特别是在子查询返回大量数据时。
解释:EXISTS
会在找到第一条匹配记录后立即返回结果,而IN
则需要构建整个结果集再进行匹配。在大数据量情况下,EXISTS
的性能优势更加明显。
示例:
-- 使用IN的写法
SELECT *
FROM orders
WHERE customer_id IN (SELECT id FROM customers WHERE region = 'North');-- 使用EXISTS的写法
SELECT *
FROM orders o
WHERE EXISTS (SELECT 1 FROM customers c WHERE c.id = o.customer_id AND c.region = 'North');
在这个例子中,使用EXISTS
避免了构建包含所有customer_id
的中间结果集,从而提高了查询效率。
3. 避免在索引列上使用计算
原则:在索引列上进行计算会导致索引失效,从而引发全表扫描。
解释:索引是预先计算并存储的,如果在索引列上进行计算(如加减乘除、函数等),数据库将无法直接使用索引,而是需要对每一行数据进行计算后再比较,这会导致性能大幅下降。
示例:
-- 不优化的写法
SELECT *
FROM orders
WHERE YEAR(order_date) = 2023;-- 优化的写法
SELECT *
FROM orders
WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31';
在优化的写法中,通过直接使用日期范围查询,避免了在order_date
列上进行YEAR
函数计算,从而能够利用索引提高查询效率。
4. 避免在索引列上使用IS NULL和IS NOT NULL
原则:在索引列上使用IS NULL
或IS NOT NULL
会导致索引失效,应尽量避免。
解释:大多数数据库对NULL
值的索引处理不够高效,使用IS NULL
或IS NOT NULL
查询时,可能会导致全表扫描,从而影响性能。
示例:
-- 不优化的写法
SELECT *
FROM customers
WHERE email IS NULL;-- 优化的写法(假设email字段允许空字符串代替NULL)
SELECT *
FROM customers
WHERE email = '';
在实际业务中,可以通过设置默认值(如空字符串)来代替NULL
,从而避免在索引列上使用IS NULL
查询。
5. 建立索引
原则:应尽量避免全表扫描,首先考虑在where
及order by
涉及的列上建立索引。
解释:索引可以显著提高查询速度,特别是在处理大量数据时。通过在where
条件和order by
排序涉及的列上建立索引,可以大大减少数据扫描的行数,从而提高查询效率。
示例:
-- 假设没有索引
SELECT *
FROM orders
WHERE customer_id = 123
ORDER BY order_date;-- 建立索引
CREATE INDEX idx_orders_customer_id ON orders(customer_id);
CREATE INDEX idx_orders_order_date ON orders(order_date);-- 使用索引后的查询
SELECT *
FROM orders
WHERE customer_id = 123
ORDER BY order_date;
在建立索引后,查询性能会显著提升,因为数据库可以直接通过索引定位到符合条件的数据行,而无需进行全表扫描。
6. 避免在where子句中对字段进行null值判断
原则:尽量避免在where
子句中对字段进行null
值判断,否则将导致索引失效。
解释:与在索引列上使用IS NULL
类似,直接在where
子句中对字段进行null
值判断也会导致索引失效,从而引发全表扫描。
示例:
-- 不优化的写法
SELECT *
FROM employees
WHERE manager_id IS NULL;-- 优化的写法(通过业务逻辑避免NULL值)
SELECT *
FROM employees
WHERE manager_id = 0; -- 假设0表示没有经理
在实际业务设计中,可以通过特殊值(如0或-1)来代替NULL
,从而避免在where
子句中进行null
值判断。
7. 避免在where子句中对字段进行表达式操作
原则:避免在where
子句中对字段进行表达式操作,这将导致索引失效。
解释:在索引列上进行表达式操作(如加减乘除、字符串操作等)会导致索引失效,因为数据库需要对每一行数据进行计算后才能进行比较。
示例:
-- 不优化的写法
SELECT *
FROM products
WHERE price * 1.1 > 100;-- 优化的写法
SELECT *
FROM products
WHERE price > 100 / 1.1;
在优化的写法中,通过将表达式移到比较值的右侧,避免了在price
列上进行计算,从而能够利用索引提高查询效率。
综合实践
结合以上优化方法,我们可以对一个复杂的查询进行综合优化。假设我们有以下两个表:orders
(订单表)和customers
(客户表),我们需要查询2023年北区客户的所有订单,并按照订单日期排序。
未优化的查询:
SELECT o.*
FROM orders o
WHERE o.customer_id IN (SELECT c.id FROM customers c WHERE c.region = 'North')AND YEAR(o.order_date) = 2023
ORDER BY o.order_date;
优化后的查询:
-- 首先建立索引
CREATE INDEX idx_customers_region ON customers(region);
CREATE INDEX idx_orders_customer_id ON orders(customer_id);
CREATE INDEX idx_orders_order_date ON orders(order_date);-- 优化后的查询
SELECT o.*
FROM orders o
JOIN customers c ON o.customer_id = c.id
WHERE c.region = 'North'AND o.order_date BETWEEN '2023-01-01' AND '2023-12-31'
ORDER BY o.order_date;
在优化后的查询中,我们做了以下改进:
- 通过
JOIN
代替子查询,提高了连接效率。 - 将
YEAR(o.order_date) = 2023
替换为日期范围查询,避免了在索引列上进行计算。 - 在
customers
表的region
列、orders
表的customer_id
列和order_date
列上建立了索引,提高了查询速度。
通过这些优化措施,我们可以显著提升查询性能,特别是在处理大量数据时。SQL语句优化是一个持续的过程,需要根据具体的业务场景和数据特点进行不断调整和优化。
相关文章:

问:SQL优化,七条实践总结?
SQL语句优化是数据库性能调优的重要部分,通过合理的优化可以显著提升查询速度和系统性能。文章总结几种常见SQL语句优化方法。 1. 优化Where子句的顺序 原则:表之间的连接条件应写在其他Where条件之前,能够过滤掉最大数量记录的条件应优先写…...

unity单例模式的不同声明(待完善
总结: 这段代码实现了一个泛型单例模式(Singleton Pattern),用于确保某个类(由泛型参数 T 指定)在整个应用程序中只有一个实例,并且在第一次访问时才创建该实例。该模式保证了该实例的全局唯一…...

大模型在蓝鲸运维体系应用——蓝鲸运维开发智能助手
本文来自腾讯蓝鲸智云社区用户: CanWay 背景 1、运维转型背景 蓝鲸平台从诞生之初,就一直在不遗余力地推动运维转型,让运维团队可以通过一体化PaaS平台,快速编写脚本,编排流程,开发运维工具,从被动地提供…...

vue2,vue3响应式的理解
vue2的话主要使用的是defineProperty对已有属性添加get,set,从而完成对数据的响应式控制,但每次需要for循环对属性进行遍历 function DefineReactive(target, key, value) {//存在多层嵌套的objectObserver(value);Object.defineReactive(target, key, {get() {retu…...

群控系统服务端开发模式-应用开发-前端退出功能
我们从未登录一直到退出,现在已经登录到操作,现在完成退出。退出有两种情况下会退出:第一种情况下是手动点击退出按钮,第二种情况下是登录过期时间到了自动退出的。 一、手动退出 因退出及个人信息页面都在公有页面,所…...

Web入门
Spring 官网:Spring | Home Spring是一个开源的Java企业级应用开发框架。Spring的主要目的是使Java EE(Java Platform, Enterprise Edition)开发更容易,并且通过提供一系列丰富的库和接口来促进良好编程实践,是…...

基于SpringBoot网上超市的设计与实现录像
基于SpringBoot网上超市的设计与实现录像 SpringBoot网上超市的设计与实现录像...

python爬虫(二)爬取国家博物馆的信息
import requests from bs4 import BeautifulSoup# 起始网址 url https://www.chnmuseum.cn/zx/xingnew/index_1.shtml # 用于存储所有数据 all_data [] page 1 global_index 1 # 定义全局序号变量并初始化为1 while True:html_url requests.get(url).textif requests.get…...

【mysql的当前读和快照读】
在MySQL中,尤其是InnoDB存储引擎中,读操作主要分为两种:当前读(Current Read)和快照读(Snapshot Read) 当前读 当前读每次读取的都是当前最新的数据。这种读操作在读取数据时不允许其他事务对这…...

[CKS] Audit Log Policy
最近准备花一周的时间准备CKS考试,在准备考试中发现有一个题目关于audit policy的题目。 专栏其他文章: [CKS] Create/Read/Mount a Secret in K8S-CSDN博客[CKS] Audit Log Policy-CSDN博客 -[CKS] 利用falco进行容器日志捕捉和安全监控-CSDN博客[CKS] K8S Netw…...

【Linux】-学习笔记03
第十一章-管理Linux软件包和进程 1.源码下载安装软件 1.1概念 源码文件:程序编写者使用C或C等语言编写的原始代码文本文件 源码文件使用.tar.gz或.tar.bz2打包成压缩文件 1.2特点 源码包可移植性好,与待安装软件的工作环境依赖性不大 由于有编译过程…...

Leetcode热题100-32 最长有效括号
Leetcode热题100-32 最长有效括号 1. 题目描述2. 解题思路动态规划栈解法 3. 代码实现动态规划栈解法 1. 题目描述 32 最长有效括号 2. 解题思路 动态规划 定义状态: 设 dp[i] 表示以位置 i 结尾的最长有效括号子串的长度。 状态转移方程: 遍历字符…...

【大数据学习 | HBASE】hbase的读数据流程与hbase读取数据
1. hbase的读数据流程 在解析读取流程之前我们还需要知道两个功能性的组件和HFIle的格式信息 HFILE 存储在hdfs中的hbase文件,这个文件中会存在hbase中的数据以kv类型显示,同时还会存在hbase的元数据信息,包括整个hfile文件的索引大小&…...

A027-基于Spring Boot的农事管理系统
🙊作者简介:在校研究生,拥有计算机专业的研究生开发团队,分享技术代码帮助学生学习,独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取,记得注明来意哦~🌹 赠送计算机毕业设计600…...

Redisson的可重入锁
初始状态: 表示系统或资源在没有线程持有锁的情况下的状态,任何线程都可以尝试获取锁。 线程 1 获得锁: 线程 1 首次获取了锁并进入受保护的代码区域。 线程 1 再次请求锁: 在持有锁的情况下,线程 1 再次请求锁&a…...

SQL Server Service Broker完整示例
目录 准备 创建Message,Contract,Queue和Service 创建调用存储过程 启用SQL Agent并创建Job执行存储过程 调用demo 常见故障排除 准备 判断你的数据库YourDatabaseName是否启用了Service Broker SELECT is_broker_enabled FROM sys.databases WH…...

CentOS7 升级OpenSSH9.0全过程和坑
近日,漏洞肆虐,需要升级新版本,才能解决漏洞。故有此文: 0 查看当前版本 [root@host-testsvc openssh-9.0p1]# ssh -V OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 20171、在data下新建一个独立目录openssh目录,用来存放软件 [root@host-testsvc data]# mkdir openssh…...

RSTP的配置
RSTP相对于STP在端口角色、端口状态、配置BPDU格式、配置BPDU的处理方式、快速收敛机制、拓扑变更机制和4种保护特性方面的详细改进说明: 端口角色: STP中定义了三种端口角色:根端口(Root Port)、指定端口࿰…...

力扣257:二叉树的所有路径
给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点。 示例 1: 输入:root [1,2,3,null,5] 输出:["1->2->5","1->3"]示例…...

Tcl 和 Python 在二次开发研究
引言 Tcl(Tool Command Language)和 Python 都是广泛应用于各种领域的编程语言,特别是在二次开发和自动化开发方面,两者有着独特的特性。Tcl 是一种动态的脚本语言,早期主要用于集成和控制其他程序,因此它经常出现在嵌入式应用和图形用户界面(GUI)开发中。而 Python 是…...

【NLP优化】Ubuntu 20.04 下 源码安装 CasADi + Ipopt / acados
20241114 记录一下 Ubuntu 20.04 下安装 MPC 中两种常用开源 NLP 优化器 CasADi + Ipopt / acados 可以新建一个文件夹,保存所有源码安装下载的代码 mkdir ~/mpc_dep1. 安装依赖 # **IPOPT** sudo apt-get install gcc g++ gfortran git patch wget pkg-config libmetis-de…...

[241110] 微软发布多智能体系统Magentic-One | 社区讨论:Ubuntu 26.04 LTS 发布前移除 Qt 5
目录 微软发布多智能体系统 Magentic-One社区讨论:Ubuntu 26.04 LTS 发布前移除 Qt 5 微软发布多智能体系统 Magentic-One 微软研究院近日发布了一个名为 Magentic-One 的多智能体系统,旨在解决复杂的现实世界任务。这个系统展现了令人兴奋的潜力&#…...

AI风向标|算力与通信的完美融合,SRM6690解锁端侧AI的智能密码
当前,5G技术已经成为推动数字经济和实体经济深度融合的关键驱动力,进入5G发展的下半场,5G与AI的融合正推动诸多行业的数字化转型和创新发展,终端侧AI和端云混合式AI将广泛应用于各类消费终端和各行各业。 在推动5G和AI与各行业场…...

MySQL查询执行(六):join查询
到底可不可以使用join 假设存在如下表结构: -- 创建表t2 CREATE TABLE t2 (id int(11) NOT NULL,a int(11) DEFAULT NULL,b int(11) DEFAULT NULL,PRIMARY KEY (id),KEY a (a) ) ENGINEInnoDB;-- 向t2写入1000条数据 drop procedure idata; delimiter ;; create pr…...

python习题练习
python习题 编写一个简单的工资管理程序系统可以管理以下四类人:工人(worker)、销售员(salesman)、经理(manager)、销售经理(salemanger)所有的员工都具有员工号,工资等属性,有设置姓名,获取姓名,获取员工号,计算工资等…...

MySQL高级(二):一条更新语句是如何执行的
执行步骤 1. 解析 SQL 语句 MySQL 首先会解析你输入的 UPDATE 语句。解析器会检查语法是否正确,并将 SQL 语句转化为内部的数据结构(通常是语法树)。 示例 SQL 语句: UPDATE employees SET salary 5000 WHERE department Sa…...

在 Ubuntu 18.04 中搭建和测试 DNS 服务器
在 Ubuntu 18.04 中搭建和测试 DNS 服务器可以通过安装和配置 BIND(Berkeley Internet Name Domain)来实现。以下是详细的步骤: 1. 安装 BIND 打开终端并运行以下命令来安装 BIND: sudo apt update sudo apt install bind9 bin…...

算法学习第一弹——C++基础
早上好啊,大佬们。来看看咱们这回学点啥,在前不久刚出完C语言写的PTA中L1的题目,想必大家都不过瘾,感觉那些题都不过如此,所以,为了我们能更好的去处理更难的题目,小白兔决定奋发图强࿰…...

javaWeb小白项目--学生宿舍管理系统
目录 一、检查并关闭占用端口的进程 二、修改 Tomcat 的端口配置 三、重新启动 Tomcat 一、javaw.exe的作用 二、结束javaw.exe任务的影响 三、如何判断是否可以结束 结尾: 这个错误提示表明在本地启动 Tomcat v9.0 服务器时遇到了问题,原因是所需…...

如何优化Elasticsearch的查询性能?
优化Elasticsearch查询性能可以从以下几个方面进行: 合理设计索引和分片: 确保设置合理的分片和副本数,考虑数据量、节点数和集群大小。根据数据量和节点数量调整分片数量,避免使用过多分片,因为每个分片都需要额外的…...