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.pswp.cn/web/72029.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/72029.shtml
英文地址,請注明出處:http://en.pswp.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;前提是你已經配置好了…