由于最近需要做一些sql query性能提升的研究,因此研究了一下sql語句的解決過程。在園子里看了下,大家寫了很多相關的文章,大家的側重點各有不同。本文是我在看了各種資料后手機總結的,會詳細的,一步一步的講述一個sql語句的各個關鍵字的解析過程,歡迎大家互相學習。
SQL語句的解析順序簡單的說一個sql語句是按照如下的順序解析的:
1. FROM FROM后面的表標識了這條語句要查詢的數據源。和一些子句如,(1-J1)笛卡爾積,(1-J2)ON過濾,(1-J3)添加外部列,所要應用的對象。FROM過程之后會生成一個虛擬表VT1。首先創建一個Customers表,插入如下數據:
customeridcity
FISSAMadrid
FRNDOMadrid
KRLOSMadrid
MRPHSZion
創建一個Orders表,插入如下數據:
orderidcustomerid
1FRNDO
2FRNDO
3KRLOS
4KRLOS
5KRLOS
6MRPHS
7NULL
假如我們想要查詢來自Madrid的,訂單數小于3的客戶,并把他們的訂單數顯示出來,結果按照訂單數從小到大進行排序。
復制代碼 代碼如下:
SELECT C.customerid, COUNT(O.orderid) AS numorders
FROM dbo.Customers AS C
LEFT OUTER JOIN dbo.Orders AS O
ON C.customerid = O.customerid
WHERE C.city = 'Madrid'
GROUP BY C.customerid
HAVING COUNT(O.orderid) < 3
ORDER BY numorders
customeridnumorders
FISSA0
FRNDO2
下面我們會詳細的講述sql是怎樣計算出這個結果的:
FROM子句FROM子句標識了需要查詢的表,如果指定了表操作,會從左到右的處理,每一個基于一個或者兩個表的表操作都會返回一個輸出表。左邊表的輸出結果會作為下一個表操作的輸入結果。例如,交表相關的操作有 (1-J1)笛卡爾積,(1-J2)ON過濾器,(1-J3)添加外部列。FROM句子生成虛擬表VT1。
Step 1-J1:執行笛卡爾積(CROSS JOIN)笛卡爾積會把左右兩個表每一行所有可能的組合都列出來生成表VT1-J1,如果左表有m列,右表有n列,那么笛卡爾積之后生成的VT1-J1表將會有m×n列。
Step 1-J1這個步驟等價于執行:
SELECT * from Customers C CROSS JOIN Orders O執行結果為:(共有4×7列)
C.customeridC.cityO.orderidO.customerid
FISSAMadrid1FRNDO
FISSAMadrid2FRNDO
FISSAMadrid3KRLOS
FISSAMadrid4KRLOS
FISSAMadrid5KRLOS
FISSAMadrid6MRPHS
FISSAMadrid7NULL
FRNDOMadrid1FRNDO
FRNDOMadrid2FRNDO
FRNDOMadrid3KRLOS
FRNDOMadrid4KRLOS
FRNDOMadrid5KRLOS
FRNDOMadrid6MRPHS
FRNDOMadrid7NULL
KRLOSMadrid1FRNDO
KRLOSMadrid2FRNDO
KRLOSMadrid3KRLOS
KRLOSMadrid4KRLOS
KRLOSMadrid5KRLOS
KRLOSMadrid6MRPHS
KRLOSMadrid7NULL
MRPHSZion1FRNDO
MRPHSZion2FRNDO
MRPHSZion3KRLOS
MRPHSZion4KRLOS
MRPHSZion5KRLOS
MRPHSZion6MRPHS
MRPHSZion7NULL
Step 1-J2:應用ON過濾,(JOIN 條件)ON過濾條件是sql的三個過濾條件(ON,WHERE,HAVING)中最先執行的,ON過濾條件應用于前一步生成的虛擬表(VT1-J1),滿足ON過濾條件的行會被加入到虛擬表VT1-J2中。在應用了ON 過濾之后,生成的VT1-J2表如下所示:
C.customeridC.cityO.orderidO.customerid
FRNDOMadrid1FRNDO
FRNDOMadrid2FRNDO
KRLOSMadrid3KRLOS
KRLOSMadrid4KRLOS
KRLOSMadrid5KRLOS
新聞熱點
疑難解答