解析 mysql_MySQL的sql解析
首先看一下示例語句
SELECT DISTINCT
< select_list >
FROM
< left_table > < join_type >
JOIN < right_table > ON < join_condition >
WHERE
< where_condition >
GROUP BY
< group_by_list >
HAVING
< having_condition >
ORDER BY
< order_by_condition >
LIMIT < limit_number >
然而它的執行順序是這樣的
1 FROM
2 ON
3 JOIN ?第二步和第三步會循環執行
4 WHERE ?第四步會循環執行,多個條件的執行順序是從左往右的。
5 GROUP BY
6 HAVING
7 SELECT 分組之后才會執行SELECT
8 DISTINCT
9 ORDER BY
10 LIMIT 前9步都是SQL92標準語法。limit是MySQL的獨有語法
來看一個例子
假設有表1和表2
table1
table2
1、from
2個表聯合查詢得到他們的笛卡爾積CROSS JOIN,產生 虛表VT1
2、ON過濾
對 虛表VT1 進行ON篩選,只有那些符合的行才會被記錄在虛表VT2中。
注意:這里因為語法限制,使用了‘WHERE‘代替,從中讀者也可以感受到兩者之間微妙的關系;
3.OUTER JOIN添加外部列
如果指定了 OUTER JOIN(比如left join、 right join) ,那么 保留表中未匹配的行 就會作為外部行 添加 到 虛
擬表VT2 中,產生 虛擬表VT3 。
如果FROM子句中包含兩個以上的表的話,那么就會對上一個join連接產生的結果VT3和下一個表重復執行步驟1~3
這三個步驟,一直到處理完所有的表為止
4.WHERE
對 虛擬表VT3 進行WHERE條件過濾。只有符合的記錄才會被插入到 虛擬表VT4 中。
5.GROUP BY
根據group by子句中的列,對VT4中的記錄進行分組操作,產生 虛擬表VT5 。
注意:
其后處理過程的語句,如SELECT,HAVING,所用到的列必須包含在GROUP BY中。對于沒有出現的,得用聚合函
數;
原因:
GROUP BY改變了對表的引用,將其轉換為新的引用方式,能夠對其進行下一級邏輯操作的列會減少;
6.HAVING
對 虛擬表VT5 應用having過濾,只有符合的記錄才會被 插入到 虛擬表VT6 中。
7.SELECT
這個子句對SELECT子句中的元素進行處理,生成VT5表。
(5-J1)計算表達式 計算SELECT 子句中的表達式,生成VT5-J1
8.DISTINCT
尋找VT5-1中的重復列,并刪掉,生成VT5-J2
如果在查詢中指定了DISTINCT子句,則會創建一張內存臨時表(如果內存放不下,就需要存放在硬盤了)。這張
臨時表的表結構和上一步產生的虛擬表VT5是一樣的,不同的是對進行DISTINCT操作的列增加了一個唯一索引,以
此來除重復數據
9.ORDER BY
從 VT5-J2 中的表中,根據ORDER BY 子句的條件對結果進行排序,生成VT6表。
注意:
唯一可使用SELECT中別名的地方
10.LIMIT(MySQL特有)
LIMIT子句從上一步得到的 VT6虛擬表 中選出從指定位置開始的指定行數據
注意:
offset 和 rows 的正負帶來的影響;
當偏移量很大時效率是很低的,可以這么做:
采用子查詢的方式優化 ,在子查詢里先從索引獲取到最大id,然后倒序排,再取N行結果集
采用INNER JOIN優化 ,JOIN子句里也優先從索引獲取ID列表,然后直接關聯查詢獲得最終結果
解析順序總結
流程分析
1. ?FROM(將最近的兩張表,進行笛卡爾積)---VT1
2. ?ON(將VT1按照它的條件進行過濾)---VT2
3. ?LEFT JOIN(保留左表的記錄)---VT3
4. ?WHERE(過濾VT3中的記錄)--VT4…VTn
5. ?GROUP BY(對VT4的記錄進行分組)---VT5
6. ?HAVING(對VT5中的記錄進行過濾)---VT6
7. ?SELECT(對VT6中的記錄,選取指定的列)--VT7
8. ?ORDER BY(對VT7的記錄進行排序)--VT8
9. ?LIMIT(對排序之后的值進行分頁)--MySQL特有的語法
流程說明:
單表查詢:根據 WHERE 條件過濾表中的記錄,形成中間表(這個中間表對用戶是不可見的);然后根據
SELECT 的選擇列選擇相應的列進行返回最終結果。
兩表連接查詢:對兩表求積(笛卡爾積)并用 ON 條件和連接連接類型進行過濾形成中間表;然后根據
WHERE條件過濾中間表的記錄,并根據 SELECT 指定的列返回查詢結果。
笛卡爾積:行相乘、列相加
多表連接查詢:先對第一個和第二個表按照兩表連接做查詢,然后用查詢結果和第三個表做連接查詢,以此
類推,直到所有的表都連接上為止,最終形成一個中間的結果表,然后根據WHERE條件過濾中間表的記錄,
并根據SELECT指定的列返回查詢結果。
總結
以上是生活随笔為你收集整理的解析 mysql_MySQL的sql解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 八卦一下“笑点低”到底低成什么样?什么才
- 下一篇: mysql第三章关系模型_一个MySQL