成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

SQL 查詢并不是從 Select 開始的

數據庫 SQL Server
日常使用中寫 SQL 查詢命令都是以 SELECT 開始的(注意:本文僅探討 SELECT 查詢,不涵蓋 insert 或其他 SQL 命令)。

[[411395]]

本文轉載自微信公眾號「HelloGitHub」,作者HelloGitHub。轉載本文請聯系HelloGitHub公眾號。

日常使用中寫 SQL 查詢命令都是以 SELECT 開始的(注意:本文僅探討 SELECT 查詢,不涵蓋 insert 或其他 SQL 命令)。

昨天我想到一個問題:可以用 WHERE、HAVING 或者其他方式來過濾窗口函數執行結果嗎?

經過一番探索,我得出的最終結論是否定的,因為窗口函數必須在 WHERE 和 GROUP BY 之后才能運行。但是,這也延伸到了一個更大的問題——SQL 查詢的執行順序是怎么樣的呢?

SQL 查詢執行順序

我專門查了一下文檔 SQL 查詢執行順序如下:

如果不喜歡以上五彩斑斕的圖片形式,也可以看下面的文字:

  1. FROM/JOIN/ON
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. SELECT(窗口函數即在此步驟執行)
  6. ORDER BY
  7. LIMIT

上圖可以解答你的如下疑惑:

上圖是 SQL 查詢的語義說明。看懂這張圖,便能迅速判斷一個給定的 SQL 查詢將會返回什么結果,也可以輕松解答如下疑問:

  • 可以對 GROUP BY 的結果進行WHERE 篩選嗎?(不可以!因為 WHERE 在 GROUP BY 之前執行)
  • 可以對窗口函數的執行結果進行過濾嗎?(不可以!因為窗口函數在 SELECT 步驟執行,而這步是在 WHERE 和 GROUP BY 之后)
  • 可以對 GROUP BY 的結果再執行 ORDER BY 操作嗎? (可以!ORDER BY 基本上是最后一個步驟了,所以可以對任何操作的執行結果執行 ORDER BY)
  • LIMIT 執行在哪個步驟? (最后一步!)

雖然如此,但實際上數據庫引擎并非嚴格按照這個順序運行查詢,因為它們還會執行一系列的優化,以便提升查詢速度。

所以:

  • 當你想了解查詢語句的有效性,或是想搞明白為什么會返回這樣一個查詢結果時,可以嘗試用該圖來解釋;
  • 但是,使用該圖是無法解釋查詢性能或索引相關問題的,它們會涉及到更多變量,因而也更為復雜。

一、最容易搞混的:列別名

比如:關聯姓和名,并對其進行分組。SQL 語法是允許這樣寫:

  1. SELECT CONCAT(first_name, ' ', last_name) AS full_name, count(*) 
  2. FROM table 
  3. GROUP BY full_name 

上面的查詢看起來像是在 SELECT 之后執行 GROUP BY,但其實 GROUP BY是先執行的,因為 GROUP BY 引用了 SELECT 中的 alias。

數據庫引擎是可以將查詢重寫為:

  1. SELECT * FROM 
  2. owners LEFT JOIN cats ON owners.id = cats.owner 
  3. WHERE cats.name = 'mr darcy' 

接著,先執行 GROUP BY 中的語句,再進行 SELECT 操作,所以上面那么寫是可行的。

此外,數據庫引擎肯定會執行一系列檢查,以確保在查詢開始運行之前,SELECT 和 GROUP BY 中的內容相匹配,因此在制定執行計劃之前,它必須將查詢語句當作一個整體來檢查。

二、查詢并非嚴格按照此順序運行(優化)

實際上,數據庫引擎并不是通過連接、過濾和分組來運行查詢,因為它實現了一系列優化來提升查詢速度,如重新排序(只要不影響最終返回結果)。

這里列舉一個簡單的例子來說明查詢的執行順序是如何影響了查詢性能。

  1. SELECT CONCAT(first_name, ' ', last_name) AS full_name, count(*) 
  2. FROM table 
  3. GROUP BY full_name 

如果只需要查找 3 個名為“mr darcy”的貓,那么執行整個左連接并匹配這兩個表中的所有行是很慢的。相反,如果先對名為“mr darcy”的貓進行篩選再去執行連接,則要快得多。在這種情況下,先執行過濾不會改變查詢的結果!

實際上,數據庫引擎還實現了許多其他的優化,使得查詢語句以另外的順序來執行,這里暫且不表。

三、不一樣的查詢語法

LINQ(C# 和 VB.NET 中的查詢語法)是按照FROM ... WHERE ... SELECT的順序來執行查詢。以下是 LINQ 查詢的示例:

  1. var teenAgerStudent = from s in studentList 
  2.                       where s.Age > 12 && s.Age < 20 
  3.                       select s; 

Pandas(Python 數據統計分析工具)也基本上是這樣工作的,盡管有時候不需要嚴格按照下面的順序來編寫代碼,但這樣也不失為一種好習慣:

  1. df = thing1.join(thing2)      # like a JOIN 
  2. df = df[df.created_at > 1000] # like a WHERE 
  3. df = df.groupby('something', num_yes = ('yes''sum')) # like a GROUP BY 
  4. df = df[df.num_yes > 2]       # like a HAVING, filtering on the result of a GROUP BY 
  5. df = df[['num_yes''something1''something']] # pick the columns I want to display, like a SELECT 
  6. df.sort_values('sometthing', ascending=True)[:30] # ORDER BY and LIMIT 
  7. df[:30] 

這并不是因為 Pandas 的強制規定,只是按照 JOIN/WHERE/GROUP BY/HAVING 的順序來編寫代碼更有助于理解底層邏輯。(值得一提的是,可以在 JOIN 之前先執行 WHERE 來提高性能,大多數數據庫引擎在實踐中也是這樣來執行的)

R 中的 dplyr(R 語言用來操作數據框的包)還允許采用不同的語法查詢不同的 SQL 數據庫,如:Postgres、MySQL 和 SQLite。

最后

當我發現 SQL 查詢語句的這種執行順序時,我其實是非常驚訝的。通過探究 SQL 查詢語句的執行順序,把我之前遇到的問題搞清楚了。也希望本文能幫助到更多的人理解 SQL 的執行順序以及如何正確編寫 SQL 查詢語句。

最后,感謝作者的授權:

原文地址:SQL queries don't start with SELECT

原文作者:Julia Evans(已授權)

譯者 & 校正:HelloGitHub-小熊熊 & 鹵蛋

 

責任編輯:武曉燕 來源: HelloGitHub
相關推薦

2022-03-13 23:19:04

元宇宙區塊鏈數字貨幣

2011-07-26 13:47:06

AndroidLinux

2017-10-18 22:18:09

2015-12-17 11:04:00

云開支云計算

2015-05-08 07:29:42

OpenStack云方案云服務成本

2011-07-28 09:45:59

云計算

2011-08-31 15:52:26

微軟

2021-06-24 08:20:15

MySQL數據庫索引

2023-06-25 20:07:57

云計算

2013-05-02 16:21:26

APP

2010-06-10 14:49:07

協議轉換器

2018-11-27 14:57:00

IPv6IPv4網絡

2021-06-11 09:23:30

微服務架構分層架構

2024-01-11 08:19:14

react打點上報功能Modal組件

2010-07-21 09:21:10

云計算

2018-02-25 19:20:13

軟件定義SD-WAN廣域網

2022-06-14 18:35:01

ID生成器語言

2022-05-05 09:17:03

文檔開源

2012-07-31 16:31:56

云計算

2013-08-16 09:34:31

VMwareOpenStack
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: avmans最新导航地址 | 久久激情视频 | 91在线视频播放 | 精品中文字幕在线观看 | 国产成人精品一区二区三区 | 免费v片在线观看 | 激情综合五月 | 日日噜噜噜夜夜爽爽狠狠视频97 | 天天插天天搞 | 免费看国产精品视频 | 日本aaa视频 | 久久精品国产99国产精品 | 欧美国产一区二区 | 91香蕉嫩草 | 色噜噜亚洲男人的天堂 | 精品国产乱码久久久久久牛牛 | 亚洲精品毛片av | 国产精品一区二区久久 | 成人天堂| 国产一二三区免费视频 | 亚洲成人中文字幕 | 国产欧美日韩精品一区二区三区 | 九九热视频这里只有精品 | 538在线精品 | 久草免费在线 | 二区国产 | 视频一区在线观看 | 久久久久国产精品 | 日本aa毛片a级毛片免费观看 | 国产网站在线免费观看 | 欧美日韩国产一区二区三区 | 国产免费高清 | 亚洲 成人 av | 精品一区在线 | 成人免费精品 | 国产精品一区二区三区在线 | 亚洲一区自拍 | 亚洲综合国产精品 | 日韩有码一区二区三区 | 国产精品久久久久久久久久久久 | 中文字幕在线剧情 |