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

news/2025/3/26 18:32:39/

SQL 优化核心策略

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

1. 子查询优化

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

  • 优化方案

    • 替换为 LEFT JOIN

      sql">-- 原查询(低效)
      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 在找到第一条匹配后终止扫描,效率更高。

  • 示例

    sql">-- 低效(子查询结果集大时)
    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 可能导致全表排序和去重,内存消耗大。

  • 优化方案

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

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

  • 优化示例

    sql">-- 低效
    SELECT DISTINCT user_id, order_date FROM orders;-- 高效(若需要聚合)
    SELECT user_id, order_date 
    FROM orders 
    GROUP BY user_id, order_date;
    sql">-- 高效(直接字段匹配)
    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 负载。

具体策略

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

sql">-- 先筛选,再转换
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 条件+游标方式(如基于时间或主键)。

sql">-- 低效(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.ppmy.cn/news/1582780.html

    相关文章

    基于C语言实现的观察者模式 以温度监控系统为例

    场景为 温度监控系统:当温度传感器检测到温度变化时,自动通知所有注册的显示器(如LCD、手机App)更新显示。 场景描述 主题(Subject):温度传感器,负责检测温度变化并通知观察者。 观察者(Observer):显示器(LCD显示器、手机App),订阅温度数据并在温度变化时更新显…

    深入解析MySQL数据库分库分表技术

    友情提示:本文内容由银河易创(https://ai.eaigx.com)AI创作平台gpt-4-turbo模型生成,仅供参考。 随着互联网应用的快速发展,单一数据库在面对大规模数据时可能会遇到性能瓶颈。因此,数据库分库分表作为一种…

    dcat-admin已完成项目部署注意事项

    必须 composer update 更新项目php artisan admin:publish 发布dcatadmin的静态资源手动创建目录(如果没有) storage/appstorage/framework/cachestorage/framework/sessionsstorage/framework/views 需检查 php不要禁用以下函数 putenvsymlinkproc_…

    OpenCV旋转估计(3)帮助构建一个最大生成树(Maximum Spanning Tree)函数findMaxSpanningTree()

    操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::detail::findMaxSpanningTree 是 OpenCV 中用于图像拼接工作流的一个函数,它帮助构建一个最大生成树(Maximum Spanni…

    【Centos7搭建Zabbix4.x监控HCL模拟网络设备:zabbix-server搭建及监控基础05

    兰生幽谷,不为莫服而不芳; 君子行义,不为莫知而止休。 5.zabbix监控HCL模拟网络设备 在保证zabbix-server与HCL网络相通的情况下进行如下操作。 5.1创建主机群 配置-主机群-创建主机群 图 19 取名,添加。 图 20 5.2 创建监控…

    国内首家,百度智能云千帆AppBuilder全面兼容MCP协议

    百度智能云千帆 AppBuilder 已兼容 MCP 协议!作为国内首家支持 MCP 协议的大模型应用开发平台(Claude、LangGraph、Cursor、Cline、N8N等海外平台已支持),千帆 AppBuilder 完成兼容后,用户可通过千帆 AppBuilder 轻松调…

    游戏引擎学习第178天

    回顾和今天的计划 我们正在进行一场直播游戏开发,完全不使用任何引擎或库,所有的代码都由我们自己编写,甚至不调用 GPU。如果你能相信的话。现在,我们正处在调试代码的阶段,决定开始开发一些不错的调试工具&#xff0…

    React + Node.js实践 仿B站评论

    仿B站评论 效果展示Node.js后端实现模拟网络请求静态结构效果展示代码部分 tab切换排序功能的实现按照热度排序按照时间排序 删除评论功能发布评论功能组件的封装完整代码App.js后端server.js 效果展示 Node.js后端实现模拟网络请求 采用了Express框架来构建服务器&#xff0c…