一些SQL优化经验(非添加索引版)

SQL 优化核心策略

伪代码示例,现实比这个复杂

1. 子查询优化

(1) 避免低效的 IN 和 NOT IN
  • 问题
    NOT IN 可能导致全表扫描,尤其是子查询结果集较大时。

  • 优化方案

    • 替换为 LEFT JOIN

      -- 原查询(低效)
      SELECT * FROM table_a 
      WHERE id NOT IN (SELECT id FROM table_b);-- 优化后
      SELECT a.* 
      FROM table_a a
      LEFT JOIN table_b b ON a.id = b.id
      WHERE b.id IS NULL;

    • 适用场景
      子查询结果集较大,且关联字段有索引。

(2) 优先使用 EXISTS 而非 IN
  • 优势
    EXISTS 在找到第一条匹配后终止扫描,效率更高。

  • 示例

    -- 低效(子查询结果集大时)
    SELECT * FROM users 
    WHERE id IN (SELECT user_id FROM orders);-- 高效
    SELECT * FROM users u
    WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id);


2. JOIN 优化

(1) 减少 DISTINCT,改用 GROUP BY
  • 问题
    DISTINCT 可能导致全表排序和去重,内存消耗大。

  • 优化方案

    -- 低效
    SELECT DISTINCT user_id, order_date FROM orders;-- 高效(若需要聚合)
    SELECT user_id, order_date 
    FROM orders 
    GROUP BY user_id, order_date;

(2) 避免关联字段使用函数或操作符
  • 问题
    关联字段的表达式(如 ||CONCAT)会导致索引失效。

  • 优化示例

    -- 低效
    SELECT DISTINCT user_id, order_date FROM orders;-- 高效(若需要聚合)
    SELECT user_id, order_date 
    FROM orders 
    GROUP BY user_id, order_date;
    -- 高效(直接字段匹配)
    SELECT * FROM table_a a
    JOIN table_b b ON a.ticket_no = b.ticket_no AND a.ticket_serial = b.ticket_serial;


3. 数据操作优化

(1) 增删改宽表数据先创建临时表

把先写入后改的结果表的程序,改为一次性写入,从而避免update操作锁表

比如:

1.insert 结果表(大表)

2.update 结果表(大表)

改为:

insert 临时表

update 临时表

insert 结果表(大表)

复杂查询改为:

1.insert 临时表 1

2.insert 临时表 2

3.insert 结果表 from 临时表1 left join 临时表2

把update ,delete结果表(大表)的语句延后执行,减少锁表时间

比如:

1.update 或者 delete 结果表

2.许多待查询的临时表

3.insert 结果表

改为:

1.许多待查询的临时表

2.update 或者 delete 结果表

3.insert 宽表

(2) 类型转换优化策略
核心原则:先筛选数据,后执行类型转换

在 SQL 查询中,优先通过原始字段类型完成数据筛选,将类型转换操作推迟到最终结果处理阶段。此策略可显著减少需处理的数据量,提升性能。

优化优势
  1. 减少计算开销

    • 仅对筛选后的结果进行类型转换,避免对全表数据的冗余处理。

    • 示例:若从 100 万行数据中筛选出 1 万行,类型转换操作量减少 99%。

  2. 避免索引失效

    • 在 WHERE 或 JOIN 条件中对字段进行类型转换(如 CAST(amount AS VARCHAR))会导致索引失效,引发全表扫描。

    • 优化后:直接基于原字段类型(如数值型 amount)筛选,确保索引生效。

  3. 降低内存与 IO 压力

    • 大数据场景下,减少中间结果集的数据处理量,降低内存和磁盘 IO 负载。

具体策略

筛选阶段保持字段原生类型,转换放在最后

-- 先筛选,再转换
SELECT id, CAST(created_at AS DATE) AS create_date  -- 转换放在最后
FROM orders 
WHERE created_at >= '2023-01-01';           -- 用原生类型过滤

4. 表设计与维护

(1) 统一关联字段类型
  • 问题
    字段类型不匹配(如 INT vs VARCHAR)会导致隐式转换和性能下降。

  • 优化方案
    与上游协商统一字段类型

(2) 视图转结果表
  • 场景
    高频查询的复杂视图(如报表接口)。

  • 优化步骤

    1. 将视图转为结果表:

      在查询结果表之前 用存储过程将结果写入结果表,然后再进行查询
    2. 查询时直接查询结果表,提升查询效果


5. 内存与 IO 优化

(1) 合理使用临时表


内存临时表减少磁盘 IO,但需注意内存容量。

(2) 分页查询优化
  • 避免 OFFSET 深度分页
    使用 WHERE 条件+游标方式(如基于时间或主键)。

-- 低效(OFFSET 100000)
SELECT * FROM orders ORDER BY id LIMIT 10 OFFSET 100000;-- 高效(基于上次查询的末尾 ID)
SELECT * FROM orders 
WHERE id > 100000 
ORDER BY id 
LIMIT 10;

6. 定期维护统计信息


更新表的统计信息(如 ANALYZE table),帮助优化器生成高效计划。 

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/75583.shtml

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

    相关文章

    <项目> 高并发服务器的HTTP协议支持

    目录 HTTP模块 模块划分与介绍 模块实现 Util模块 HTTPRequest模块 HTTPResponse模块 HTTPContext模块 ParseHttpLine RecvHttpLine RecvHttpHead ParseHttpHead RecvHttpBody 对外接口 HttpServer模块 OnConnected OnMessage Route IsFileHandler FileHandler Dispatcher …

    基于Spring Boot + Vue的银行管理系统设计与实现

    基于Spring Boot Vue的银行管理系统设计与实现 一、引言 随着金融数字化进程加速,传统银行业务向线上化转型成为必然趋势。本文设计并实现了一套基于Spring Boot Vue的银行管理系统,通过模块化架构满足用户、银行职员、管理员三类角色的核心业务需求…

    微软提出 Logic-RL:基于规则的强化学习释放大语言模型推理能力

    ❝ 更多 LLM 架构文章点击查看: LLM 架构专栏 大模型架构专栏文章阅读指南 1. AI 智能体,颠覆还是赋能?一文读懂! 2. 1W8000 字 解锁 AI 高效运作密码:工作流与智能体如何协同? 3. 万字深度剖析 AI 代理&am…

    STM32八股【1】-----启动流程和startup文件理解

    启动流程 知识点 MCU 上电复位。MSP从向量表第0个地址读取一个32位(2字节)的值并保存,该值为栈顶地址。PC计数器从第1个地址读取一个两字节的值并保存,该值为程序入口,一般是Reset_Handler。想了解FLASH地址映射可以…

    详解c++20的协程,自定义可等待对象,生成器详解

    协程 c20的协程三大标签:“性能之优秀”,“开发之灵活”,“门槛之高” 在讲解c的协程使用前,我们需要先明白协程是什么,协程可以理解为用户态的线程,它需要由程序来进行调度,如上下文切换与调…

    JavaEE企业级开发 延迟双删+版本号机制(乐观锁) 事务保证redis和mysql的数据一致性 示例

    提醒 要求了解或者熟练掌握以下知识点 spring 事务mysql 脏读如何保证缓存和数据库数据一致性延迟双删分布式锁并发编程 原子操作类 前言 在起草这篇博客之前 我做了点功课 这边我写的是一个示例代码 数据层都写成了 mock 的形式(来源于 JUnit5) // Dduo import java.u…

    A2 最佳学习方法

    记录自己想法的最好理由是发现自己的想法,并将其组织成可传播的形式 (The best reason for recording what one thinks is to discover what one thinks and to organize it in transmittable form.) Prof Ackoff 经验之谈: 做培训或者写文章&#xff…

    嵌入式硬件工程师从小白到入门-PCB绘制(二)

    PCB绘制从小白到入门:知识点速通与面试指南 一、PCB设计核心流程 需求分析 明确电路功能(如电源、信号处理、通信)。确定关键参数(电压、电流、频率、接口类型)。 原理图设计 元器件选型:匹配封装、电压、…

    vue创建子组件步骤及注意事项

    在 Vue 中创建子组件需要遵循组件化开发的核心原则,并注意数据流、通信机制、复用性等关键点。以下是详细步骤和注意事项,结合代码示例说明: 一、创建子组件的步骤 1. 定义子组件 创建一个 .vue 文件(单文件组件)&am…

    Cocos Creator版本发布时间线

    官网找不到,DeepSeek给的答案,这里做个记录。 Cocos Creator 1.x 系列 发布时间:2016 年 - 2018 年 1.0(2016 年 3 月): 首个正式版本,基于 Cocos2d-x 的 2D 游戏开发工具链,集成可…

    【Spring AI】基于专属知识库的RAG智能问答小程序开发——功能优化:用户鉴权主体功能开发

    系列文章目录 【Spring AI】基于专属知识库的RAG智能问答小程序开发——完整项目(含完整前端后端代码)【Spring AI】基于专属知识库的RAG智能问答小程序开发——代码逐行精讲:核心ChatClient对象相关构造函数【Spring AI】基于专属知识库的R…

    【AI神经网络】深度神经网络(DNN)技术解析:从原理到实践

    引言 深度神经网络(Deep Neural Network, DNN)作为人工智能领域的核心技术,近年来在计算机视觉、自然语言处理、医疗诊断等领域取得了突破性进展。与传统机器学习模型相比,DNN通过多层非线性变换自动提取数据特征,解决…

    目标跟踪——deepsort算法详细阐述

    deepsort 算法详解 Unmatched Tracks(未匹配的轨迹) 本质角色: 是已存在的轨迹在当前帧中“失联”的状态,即预测位置与检测结果不匹配。 生命周期阶段: 已初始化: 轨迹已存在多帧,可能携带历史信息(如外观特征、运动模型)。 未被观测到: 当前帧中未找到对应的检测框…

    Vue-admin-template安装教程

    #今天配置后台管理模板发现官方文档的镜像网站好像早失效了,自己稍稍总结了一下方法# 该项目环境需要node17及以下,如果npm install这一步报错可能是这个原因 git clone https://github.com/PanJiaChen/vue-admin-template.git cd vue-admin-template n…

    Rust从入门到精通之进阶篇:14.并发编程

    并发编程 并发编程允许程序同时执行多个独立的任务,充分利用现代多核处理器的性能。Rust 提供了强大的并发原语,同时通过类型系统和所有权规则在编译时防止数据竞争和其他常见的并发错误。在本章中,我们将探索 Rust 的并发编程模型。 线程基…

    算法训练营第二十三天 | 贪心算法(一)

    文章目录 一、贪心算法理论基础二、Leetcode 455.分发饼干二、Leetcode 376. 摆动序列三、Leetcode 53. 最大子序和 一、贪心算法理论基础 贪心算法是一种在每一步选择中都采取当前状态下的最优决策,从而希望最终达到全局最优解的算法设计技术。 基本思想 贪心算…

    css基础-display 常用布局

    CSS display 属性详解 属性设置元素是否被视为块级或行级盒子以及用于子元素的布局,例如流式布局、网格布局或弹性布局。 一、基础显示模式 1. block 作用: 元素独占一行可设置宽高和内外边距默认宽度撑满父容器 应用场景: 布局容器&a…

    速卖通API数据清洗实战:从原始JSON到结构化商品数据库

    下面将详细介绍如何把速卖通 API 返回的原始 JSON 数据清洗并转换为结构化商品数据库。 1. 数据获取 首先要借助速卖通 API 获取商品数据,以 Python 为例,可使用requests库发送请求并得到 JSON 数据。 import requests# 替换为你的 API Key 和 Secret …

    【零基础入门unity游戏开发——2D篇】2D物理系统 —— 2D刚体组件(Rigidbody2D)

    考虑到每个人基础可能不一样,且并不是所有人都有同时做2D、3D开发的需求,所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】:主要讲解C#的基础语法,包括变量、数据类型、运算符、流程控制、面向对象等,适合没有编程基础的…

    Collectors.toMap / list 转 map

    前言 略 Collectors.toMap List<User> userList ...; Map<Long, User> userMap userList.stream().collect(Collectors.toMap(User::getUserId, Function.identity()));假如id存在重复值&#xff0c;则会报错Duplicate key xxx, 解决方案 两个重复id中&#…