SQL开发中改善查询性能的N种写法

文章目录

    • 1. 使用 SELECT *
    • 2. 在 WHERE 子句中使用函数或计算
    • 3. 使用隐式类型转换
    • 4. 不使用索引的列进行连接(JOIN)或过滤
    • 5. 使用 OR 代替 IN
    • 6. 在子查询中使用 SELECT *
    • 7. 忽略索引统计信息
    • 8. 嵌套子查询过多
    • 9. 过度使用 DISTINCT
    • 10. 使用不当的 JOIN 类型
    • 总结

在SQL开发中,某些写法可能会显著影响查询性能,甚至让系统变得非常缓慢。这里列出一些常见的“坑”,并解释它们为什么会影响性能,以及如何避免这些坑。

1. 使用 SELECT *

问题:

SELECT * FROM employees;

影响: - 返回所有列,可能导致网络传输大量不必要的数据。 - 如果表结构发生变化,查询结果也可能随之变化,导致客户端代码出错。

改进:

SELECT id, name, position FROM employees;

只选择需要的列。

2. 在 WHERE 子句中使用函数或计算

问题:

SELECT * FROM orders WHERE YEAR(order_date) = 2023;

影响: - 阻止数据库使用索引。 - 每次查询都需要对每一行进行函数计算。

改进:

SELECT * FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31';

或者使用日期函数在查询外部计算日期范围。

3. 使用隐式类型转换

问题:

SELECT * FROM users WHERE user_id = '123'; -- user_id 是整数类型

影响: - 可能导致索引失效。 - 数据库需要执行类型转换。

改进:

SELECT * FROM users WHERE user_id = 123;

确保类型匹配。

4. 不使用索引的列进行连接(JOIN)或过滤

问题:

SELECT * FROM orders o JOIN customers c ON o.customer_name = c.name;

影响: - 如果 customer_name 和 name 不是索引列,性能会很差。

改进:

-- 假设 customer_id 是外键
SELECT * FROM orders o JOIN customers c ON o.customer_id = c.id;

确保连接条件中的列有索引。

5. 使用 OR 代替 IN

问题:

SELECT * FROM employees WHERE department = 'HR' OR department = 'Finance';

影响: - 通常比使用 IN 更慢。

改进:

SELECT * FROM employees WHERE department IN ('HR', 'Finance');

6. 在子查询中使用 SELECT *

问题:

SELECT * FROM employees WHERE id IN (SELECT id FROM employees_backup WHERE status = 'active');

影响: - 可能导致大量数据传输和内存消耗。

改进:

SELECT * FROM employees WHERE id IN (SELECT id FROM employees_backup WHERE status = 'active' AND id IS NOT NULL);
-- 或者只选择必要的列
SELECT e.* FROM employees e WHERE e.id IN (SELECT id FROM employees_backup WHERE status = 'active');

7. 忽略索引统计信息

问题: 数据库统计信息过时,导致优化器选择错误的执行计划。

影响: - 查询性能下降。

改进: 定期更新统计信息,例如在 PostgreSQL 中:

ANALYZE employees;

8. 嵌套子查询过多

问题:

SELECT * FROM (SELECT * FROM (SELECT * FROM employees WHERE status = 'active') AS subquery1 WHERE department = 'HR') AS subquery2;

影响: - 每层子查询都会消耗资源。

改进:

SELECT * FROM employees WHERE status = 'active' AND department = 'HR';

9. 过度使用 DISTINCT

问题:

SELECT DISTINCT column1, column2 FROM large_table;

影响: - 排序和去重操作非常耗时。

改进: - 尽量避免使用 DISTINCT,或者通过其他方式(如 GROUP BY)实现。

10. 使用不当的 JOIN 类型

问题:

SELECT * FROM employees e LEFT JOIN departments d ON e.department_id = d.id WHERE d.name IS NULL;

影响: - 使用 LEFT JOIN 但过滤掉右表的数据,等效于 INNER JOIN 加过滤条件,但性能更差。

改进:

SELECT * FROM employees e WHERE e.department_id NOT IN (SELECT id FROM departments);

或者使用 NOT EXISTS:

SELECT * FROM employees e WHERE NOT EXISTS (SELECT 1 FROM departments d WHERE e.department_id = d.id);

总结

  • 选择必要的列
  • 避免在 WHERE 子句中使用函数
  • 确保类型匹配
  • 使用索引列进行连接和过滤
  • 优先使用 IN 而非 OR
  • 定期更新统计信息
  • 减少嵌套子查询
  • 谨慎使用 DISTINCT
  • 选择适当的 JOIN 类型

遵循这些原则,可以显著提升 SQL 查询的性能。

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

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

相关文章

第十八:go 并发 goroutine

channel 可以让多个goroutine 之间实现通信 Add方法调用时机:必须在goroutine 启动之前调用Add方法来增加计数器的值。 如果在goroutine已经启动之后再调用Add,可能会导致Wait方法提前返回,因为计数器没有正确反映正在运行的goroutine的数量…

数字IC后端项目典型问题(2025.03.10数字后端项目问题记录)

小编发现今天广大学员发过来的问题都比较好,立即一顿输出分享给大家(每天都有好多种类的数字后端问题)。后续可能会经常通过这种方式来做分享。其实很多问题都是实际后端项目中经常遇到的典型问题。希望通过这种方式的分享能够帮助到更多需要…

课程《Deep Learning Specialization》

在coursera上,Deep Learning Specialization 课程内容如下图所示: Week2 assignment, Logistic Regression.

LLM推理和优化(1):基本概念介绍

一、LLM推理的核心过程:自回归生成 LLM(如DeepSeek、ChatGPT、LLaMA系列等)的推理本质是自回归生成:从初始输入(如[CLS]或用户prompt)开始,逐token预测下一个词,直到生成结束符&…

【从零开始学习计算机科学】编译原理(一)编译过程概述

【从零开始学习计算机科学】编译原理(一)编译过程概述 绪论编译过程概述词法分析语法分析代码优化代码生成其他功能编译器的前端和后端绪论 什么叫编译程序?为什么我们需要编译程序?编译程序就是一个程序,将便于人编写、阅读、维护的高级计算机语言所写作的源代码程序,翻…

3-001:MySQL 中的回表是什么?

1. 什么是回表? 回表(Back to Table) 指的是 在使用非聚簇索引(辅助索引)查询时,MySQL 需要 先通过索引找到主键 ID,然后再回到主键索引(聚簇索引)查询完整数据&#xf…

【AIGC】计算机视觉-YOLO系列家族

YOLO系列家族 (1)YOLO发展史(2) YOLOX(3) YOLOv6(4) YOLOv7(5) YOLOv8(6) YOLOv9(7)YOLOv10(8&…

基于Python懂车帝汽车数据分析平台(源码+lw+部署文档+讲解),源码可白嫖!

摘要 时代在飞速进步,每个行业都在努力发展现在先进技术,通过这些先进的技术来提高自己的水平和优势,汽车数据分析平台当然不能排除在外。本次我所开发的懂车帝汽车数据分析平台是在实际应用和软件工程的开发原理之上,运用Python…

Prompt 工程

一、提示原則 import openai import os import openai from dotenv import load_dotenv, find_dotenv from openai import OpenAI def get_openai_key():_ load_dotenv(find_dotenv())return os.environ[OPENAI_API_KEY]client OpenAI(api_keyget_openai_key(), # This is …

MySQL -- 数据库基础

1、基础登录操作 mysql 指定选项 选项&#xff1a; <1> -h 指定ip地址&#xff0c;即连接的主机&#xff0c;不带时&#xff0c;默认连本机 <2> -P 指定的端口号&#xff0c;指定默认端口号&#xff08;配置文件中进行配置&#xff09; <3>-u 指定的用户 &l…

02C#基本结构篇(D3_内部类-代码块-数据类型-变量-常量-字面量-运算符-流程控制语句)

目录 一、内部类 1. 定义内部类 2. 创建内部类的实例 3. 访问外部类的私有成员 4. 内部静态类 5. 使用场景和优点 6. 注意事项 ------------------------------------------- 二、代码块 1. 控制流语句 1.1. 条件语句 1> if 语句 2> switch 语句 1.2. 循环语…

15 | 定义简洁架构 Store 层的数据类型

提示&#xff1a; 所有体系课见专栏&#xff1a;Go 项目开发极速入门实战课&#xff1b;欢迎加入 云原生 AI 实战 星球&#xff0c;12 高质量体系课、20 高质量实战项目助你在 AI 时代建立技术竞争力&#xff08;聚焦于 Go、云原生、AI Infra&#xff09;&#xff1b;本节课最终…

CSDN统计个人创作总字数

前言 不是很懂爬虫&#xff0c;所以就叫deepseek写了一个 用起来很简单&#xff0c;但是有一个小问题&#xff0c;就是统计的是总字符数。代码片会被统计进去&#xff0c;Markdown语法也会被统计进去。 不过我没有太多需求&#xff0c;能大概统计一下满足以下小小的好奇心和成…

React.js 基础与进阶教程

React.js 基础与进阶教程 React.js 是由 Facebook 开发的流行前端 JavaScript 库&#xff0c;专为构建用户界面&#xff08;UI&#xff09;设计&#xff0c;尤其适用于单页面应用&#xff08;SPA&#xff09;。它采用组件化开发模式&#xff0c;使 UI 结构更加清晰、可维护性更…

msf(Metasploit)中Session与Channel的区别与关系解析

在 Metasploit Framework&#xff08;MSF&#xff09;中&#xff0c;Session 和 Channel 都是与目标主机的交互方式&#xff0c;但它们的作用和概念有所不同。本文将解析这两个术语的区别。 一、Session&#xff08;会话&#xff09; Session 是指通过 Metasploit 成功利用目标…

设计模式-结构型模式-装饰器模式

概述 装饰器模式 : Decorator Pattern : 是一种结构型设计模式. 作用 &#xff1a; 允许你动态地给对象添加功能或职责&#xff0c;而无需修改其原始类的代码,非常的符合 开闭原则。 实现思路 &#xff1a;通过创建一个包装对象&#xff08;即装饰器&#xff09;&#xff0c;来…

Qt/C++音视频开发82-系统音量值获取和设置/音量大小/静音

一、前言 在音视频开发中&#xff0c;音量的控制分两块&#xff0c;一个是控制播放器本身的音量&#xff0c;绝大部分场景都是需要控制这个&#xff0c;这个不会影响系统音量的设置。还有一种场景是需要控制系统的音量&#xff0c;因为播放器本身的音量是在系统音量的基础上控…

基于深度学习的医学CT图像肺结节智能检测与语音提示系统【python源码+Pyqt5界面+数据集+训练代码】

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

前端小食堂 | Day14 - Vue 3 の传送门与悬念

&#x1f300; 今日秘技&#xff1a;Teleport 与 Suspense の时空魔法 1. Teleport 任意门 <template> <!-- &#x1f6aa; 将组件传送到 body 末尾 --> <Teleport to"body"> <div class"modal"> <h2>重要通知&#x…

emacs使用mongosh的方便工具发布

github项目地址: GitHub - csfreebird/emacs_mongosh: 在emacs中使用mongosh快速登录mongodb数据库 * 用途 在emacs中使用mongosh快速登录mongodb数据库&#xff0c; 操作方法: M-x mongosh, 输入数据库名称&#xff0c;然后就可以自动登录&#xff0c;前提是你已经配置好了…