SQL語句執行順序相關問題

来源:https://www.cnblogs.com/phpphp/p/18013733
-Advertisement-
Play Games

註意本文是SQL執行順序,不是MySQL Server內部執行流程。 MySQL並非像PostgreSQL(被認為是最接近 SQL 標準的資料庫之一)一樣嚴格按照SQL標準,MySQL執行引擎會根據查詢的具體情況和優化策略來決定具體的執行順序,所以SQL執行順序是理論順序。 書寫順序 select. ...


註意本文是SQL執行順序,不是MySQL Server內部執行流程。
MySQL並非像PostgreSQL(被認為是最接近 SQL 標準的資料庫之一)一樣嚴格按照SQL標準,MySQL執行引擎會根據查詢的具體情況和優化策略來決定具體的執行順序,所以SQL執行順序是理論順序。

書寫順序

select...from...join...on...where...group by...having...order by...limit...

執行順序

from->join->on->where->group by->having->select->order by->limit

SQL書寫順序與執行順序不一致的原因?

SQL語言設計受到了數學中的關係代數和元組演算的影響。這些數學理論中並沒有考慮操作順序,歷史原因造成SQL書寫上的差異。
中國的語法是姓在前名在後,英文的反過來。國內是年月日,英文是月日年,文化上的差異,也是造成SQL順序彆扭的原因之一。

SQL執行順序的邏輯是什麼?

  1. from用於確定操作對象,放第一位毋庸置疑。
  2. join和on用於關聯,後面的各種處理邏輯依附於關聯後內部創建的臨時表,先生成數據集,才能為後續處理做基礎。
  3. where用於篩選,可以減少後續操作的數據量,提高查詢性能。
  4. group by用於對數據進行分類彙總,不放where前面,是為了避免分組後的數據被where過濾掉(分組分了個寂寞),造成算力浪費和記憶體資源(數據量大還是很消耗算力和記憶體的)的問題。
  5. having用於對分組結果進行過濾,所以要在group by之後。
  6. select用於決定迭代顯示那些列,而不是限制只有這些列才可以參與處理,上游的各種操作(如複雜的where條件)不能受select欄位的影響,這也是where後面跟的欄位,不必在select出現的原因。select的本意是處理數據後僅僅返回這些欄位,而不是決定只有這些欄位進行數據處理,所以必定要放偏後的位置。
  7. order by用於結果進行排序,肯定是結果處理後才排序的,理由和group by相似。
  8. limit用於限制返回結果的行數和偏移量,必須是等篩選完分組完拍完序之後再限制,否則可能導致結果有誤。

為什麼SQL執行不是先group by再where?

先分組再篩選,邏輯上說的過去,相當於整理好數據再篩選,類似於創建索引和使用索引的過程,這也是問題的由來。
如果group by放在where之前執行,則需要對大量數據進行分組,分組後還要對每個組進行篩選,事先分組好的部分數據又被過濾掉了,造成算力和記憶體浪費,可能導致記憶體不足或者性能問題,這不是一個優秀的選擇,倒不如先篩選過濾大量數據,然後對少量數據分組。

為什麼SQL執行要先select再order by?

嘗試select field2 from table order by field1,select後面沒跟order by後面的field1也不報錯。
根據結果反推:select影響不到order by,所以先order by在select也說的過去。
但是:select欄位的別名可以在order by中使用,如果反過來就達不到這樣的效果了。

為什麼MySQL的where比having效率更高?

mysql執行時,先執行from用於定位操作對象,然後就是where,可能百萬條的數據經過where之後只剩下幾十條,然後在進行之後的操作。而group by比where多了一個環節。

聚合函數參與篩選條件,為什麼只能用having?

//報錯,Invalid use of group function
select field from table where avg(field) > 2
//需要修改為
select field from table group by field having avg(field) > 2

聚合函數(常見的avg、sum、count、min、max)需要在分組之後才能計算,執行到where時還沒有分組,此時對分組進行數據處理,所以報錯。相當於要喝一口還沒生產的可樂,不符合事物的發展規律。

為什麼使用聚合函數有分組的前提?

所謂聚合函數,就是對一組數據進行彙總計算,所以有分組的前提。即便沒有使用group by顯式聲明,SQL也會對上游過來的數據集進行預設分組(隱式分組)。

為什麼欄位別名不能在where中使用?

where執行在select之前,此時別名未生效。

為什麼group by和having執行順序優先於select,卻可以使用欄位別名?

可以肯定進行了預載入,不然一定找不到別名,會報錯的。
參考官網:https://dev.mysql.com/doc/refman/8.0/en/group-by-handling.html
文章說:標準 SQL 也不允許在子句中使用別名,MySQL擴展了標準SQL以允許別名。標準 SQL 不允許在子句中使用別名,MySQL擴展了標準SQL,詳細的底層原理,文檔並未說明。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • `async` 和 `defer` 是兩種不同的JavaScript特性,它們的主要區別在於它們的執行順序和時間點。 `async` 意味著函數或代碼塊會被非同步執行。當瀏覽器遇到帶有 `async` 屬性的資源時,它會立即開始下載該資源,同時繼續載入頁面。這樣可以避免由於同步執行而導致的頁面載入阻 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 如何實現一個雨滴落下效果 前言 下雨天坐在車窗前,看著雨滴順著車窗漸漸落下,這一唯美的場景,忍不住想記錄下來。最近在糾結電腦壁紙時,無意間看到有類似的場景,可以將自己喜歡的壁紙加上這種效果。作為多年切圖仔,不由地想到了用css動畫應該可以 ...
  • 描述 這是一個用於 Tampermonkey 或其他支持用戶腳本的瀏覽器擴展的油猴腳本。 看到論壇經常有小伙伴們需要下載某創力文檔-某人文庫一些免費文檔,但是相關網站瀏覽體驗不好各種廣告,各種登錄驗證,需要很多步驟才能下載文檔,該腳本就是為瞭解決您的煩惱而誕生,儘可能做到自動化。 安裝 安裝 Tam ...
  • 已經用 uni-app+vue3+ts 開發了一段時間,記錄一下日常遇見的問題和解決辦法 uni-app 中的單端代碼 uni-app 是支持多端,如果你想讓你的代碼,只在部分平臺使用,那麼就需要用的它的單端處理語法 //#ifdef 和 //#ifndef 等。 1. //#ifdef xxx 只 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 前端開發中難免會遇到價格和金額計算的需求,這類需求所要計算的數值大多數情況下是要求精確到小數點後的多少位。但是因為JS語言本身的缺陷,在處理浮點數的運算時會出現一些奇怪的問題,導致計算不精確。 本文嘗試從現象入手,分析造成這一問題原 ...
  • 廢話不多說,龍年騰雲特效送給大家 預覽 線上預覽 龍年騰雲 源碼 龍是使用的 svg,你也可以替換成其他樣式的龍,而雲是圖片轉化成的 base64 編碼,所以整個文件就是一個 html。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
  • 本文介紹了GNU項目與Linux系統的關係,GNU項目提供了許多自由軟體,其中一些成為了Linux系統的核心組件。文章還討論了Shell的概念以及在Linux中的應用,以及X Window System和GNOME桌面環境在提供圖形界面方面的作用。 ...
  • 痞子衡嵌入式半月刊: 第 91 期 這裡分享嵌入式領域有用有趣的項目/工具以及一些熱點新聞,農曆年分二十四節氣,希望在每個交節之日準時發佈一期。 本期刊是開源項目(GitHub: JayHeng/pzh-mcu-bi-weekly),歡迎提交 issue,投稿或推薦你知道的嵌入式那些事兒。 上期回顧 ...
一周排行
    -Advertisement-
    Play Games
  • 最近做項目過程中,使用到了海康相機,官方只提供了C/C++的SDK,沒有搜尋到一個合適的封裝了的C#庫,故自己動手,簡單的封裝了一下,方便大家也方便自己使用和二次開發 ...
  • 前言 MediatR 是 .NET 下的一個實現消息傳遞的庫,輕量級、簡潔高效,用於實現進程內的消息傳遞機制。它基於中介者設計模式,支持請求/響應、命令、查詢、通知和事件等多種消息傳遞模式。通過泛型支持,MediatR 可以智能地調度不同類型的消息,非常適合用於領域事件處理。 在本文中,將通過一個簡 ...
  • 前言 今天給大家推薦一個超實用的開源項目《.NET 7 + Vue 許可權管理系統 小白快速上手》,DncZeus的願景就是做一個.NET 領域小白也能上手的簡易、通用的後臺許可權管理模板系統基礎框架。 不管你是技術小白還是技術大佬或者是不懂前端Vue 的新手,這個項目可以快速上手讓我們從0到1,搭建自 ...
  • 第1章:WPF概述 本章目標 瞭解Windows圖形演化 瞭解WPF高級API 瞭解解析度無關性概念 瞭解WPF體繫結構 瞭解WPF 4.5 WPF概述 ​ 歡迎使用 Windows Presentation Foundation (WPF) 桌面指南,這是一個與解析度無關的 UI 框架,使用基於矢 ...
  • 在日常開發中,並不是所有的功能都是用戶可見的,還在一些背後默默支持的程式,這些程式通常以服務的形式出現,統稱為輔助角色服務。今天以一個簡單的小例子,簡述基於.NET開發輔助角色服務的相關內容,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 第3章:佈局 本章目標 理解佈局的原則 理解佈局的過程 理解佈局的容器 掌握各類佈局容器的運用 理解 WPF 中的佈局 WPF 佈局原則 ​ WPF 視窗只能包含單個元素。為在WPF 視窗中放置多個元素並創建更貼近實用的用戶男面,需要在視窗上放置一個容器,然後在這個容器中添加其他元素。造成這一限制的 ...
  • 前言 在平時項目開發中,定時任務調度是一項重要的功能,廣泛應用於後臺作業、計劃任務和自動化腳本等模塊。 FreeScheduler 是一款輕量級且功能強大的定時任務調度庫,它支持臨時的延時任務和重覆迴圈任務(可持久化),能夠按秒、每天/每周/每月固定時間或自定義間隔執行(CRON 表達式)。 此外 ...
  • 目錄Blazor 組件基礎路由導航參數組件參數路由參數生命周期事件狀態更改組件事件 Blazor 組件 基礎 新建一個項目命名為 MyComponents ,項目模板的交互類型選 Auto ,其它保持預設選項: 客戶端組件 (Auto/WebAssembly): 最終解決方案裡面會有兩個項目:伺服器 ...
  • 先看一下效果吧: isChecked = false 的時候的效果 isChecked = true 的時候的效果 然後我們來實現一下這個效果吧 第一步:創建一個空的wpf項目; 第二步:在項目裡面添加一個checkbox <Grid> <CheckBox HorizontalAlignment=" ...
  • 在編寫上位機軟體時,需要經常處理命令拼接與其他設備進行通信,通常對不同的命令封裝成不同的方法,擴展稍許麻煩。 本次擬以特性方式實現,以兼顧維護性與擴展性。 思想: 一種命令對應一個類,其類中的各個屬性對應各個命令段,通過特性的方式,實現其在這包數據命令中的位置、大端或小端及其轉換為對應的目標類型; ...