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>
(7) SELECT (8) DISTINCT <select_list> (1) FROM <left_table> (3) <join_type> JOIN <right_table> (2) ON <join_condition> (4) WHERE <where_condition> (5) GROUP BY <group_by_list> (6) HAVING <having_condition> (9) ORDER BY <order_by_condition> (10) LIMIT <limit_number>
一、執行FROM語句數據庫
第一步是執行from語句,找到<left_table>
和<right_table>
兩張表,再作笛卡爾積,不論是否有對應關係,全都作好對應。把兩張表的記錄所有拼到一塊兒。獲得第一張虛擬表VT1。緩存
二、執行ON過濾大數據
第二步執行ON關鍵字,一個連表的依據,只取leftt_able.xx=right_table.xx的一個字段。在笛卡爾積的基礎上,取兩張表有對應關係的記錄。獲得第二張虛擬表VT2。spa
三、添加外部行code
實際就是實行JOIN類型,如LEFT OUTER JOIN
、RIGHT OUTER JOIN
和FULL OUTER JOIN
。在大多數的時候,咱們都是會省略掉OUTER
關鍵字的,但OUTER
表示的就是外部行的概念。在VT2的基礎留下左表或者右邊呃記錄,獲得虛擬表VT3。blog
四、執行where過濾排序
添加外部行獲得的VT3進行WHERE過濾,只有符合<where_condition>的記錄纔會輸出到虛擬表VT4中。索引
五、執行GROUP BY分組內存
GROU BY
子句主要是對使用WHERE
子句獲得的虛擬表進行分組操做。獲得的內容會存入虛擬表VT5中,此時,咱們就獲得了一個VT5虛擬表開發
六、執行HAVING過濾
HAVING
子句主要和GROUP BY
子句配合使用,對分組獲得的VT5虛擬表進行條件過濾。獲得VT6虛擬表
七、SELECT列表
如今纔會執行到SELECT
子句(不要覺得SELECT
子句被寫在第一行,就是第一個被執行的)。
執行SELECT語句從VT6中選擇出須要的內容。
八、DISTINCT子句
若是在查詢中指定了DISTINCT
子句,則會建立一張內存臨時表(若是內存放不下,就須要存放在硬盤了)。
臨時表的表結構和上一步產生的虛擬表VT7是同樣的,不一樣的是對進行DISTINCT操做的列增長了一個惟一索引,以此來除重複數據。
九、ORDER BY子句
對虛擬表中的內容按照指定的列進行排序,而後返回一個新的虛擬表VT8。
十、執行LIMIT子句
LIMIT
子句從上一步獲得的VT8虛擬表中選出從指定位置開始的指定行數據。對於沒有應用ORDER BY的LIMIT子句,獲得的結果一樣是無序的,因此,不少時候,咱們都會看到LIMIT子句會和ORDER BY子句一塊兒使用。
MySQL數據庫的LIMIT支持以下形式的選擇:
LIMIT n, m
表示從第n條記錄開始選擇m條記錄。而不少開發人員喜歡使用該語句來解決分頁問題。對於小數據,使用LIMIT子句沒有任何問題,當數據量很是大的時候,使用LIMIT n, m
是很是低效的。由於LIMIT的機制是每次都是從頭開始掃描,若是須要從第60萬行開始,讀取3條數據,就須要先掃描定位到60萬行,而後再進行讀取,而掃描的過程是一個很是低效的過程。因此,對於大數據處理時,是很是有必要在應用層創建必定的緩存機制(如今的大數據處理,大都使用緩存)