问: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 是…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...

如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...