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

问: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条件连接orderscustomers表,然后通过最能缩小结果集的条件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 NULLIS NOT NULL会导致索引失效,应尽量避免。

解释:大多数数据库对NULL值的索引处理不够高效,使用IS NULLIS NOT NULL查询时,可能会导致全表扫描,从而影响性能。

示例

-- 不优化的写法
SELECT * 
FROM customers 
WHERE email IS NULL;-- 优化的写法(假设email字段允许空字符串代替NULL)
SELECT * 
FROM customers 
WHERE email = '';

在实际业务中,可以通过设置默认值(如空字符串)来代替NULL,从而避免在索引列上使用IS NULL查询。

5. 建立索引

原则:应尽量避免全表扫描,首先考虑在whereorder 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;

在优化后的查询中,我们做了以下改进:

  1. 通过JOIN代替子查询,提高了连接效率。
  2. YEAR(o.order_date) = 2023替换为日期范围查询,避免了在索引列上进行计算。
  3. 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)、指定端口&#xff0…...

力扣257:二叉树的所有路径

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

Tcl 和 Python 在二次开发研究

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

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

​​企业大模型服务合规指南:深度解析备案与登记制度​​

伴随AI技术的爆炸式发展&#xff0c;尤其是大模型&#xff08;LLM&#xff09;在各行各业的深度应用和整合&#xff0c;企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者&#xff0c;还是积极拥抱AI转型的传统企业&#xff0c;在面向公众…...