sql的執行原理和執行順序

一、sql語句的執行步驟:
1)語法分析,分析語句的語法是否符合規範,衡量語句中各表達式的意義。
2) 語義分析,檢查語句中涉及的所有數據庫對象是否存在,且用戶有相應的權限。
3)視圖轉換,將涉及視圖的查詢語句轉換爲相應的對基表查詢語句。
4)表達式轉換, 將複雜的 SQL 表達式轉換爲較簡單的等效連接表達式。
5)選擇優化器,不同的優化器一般產生不同的“執行計劃”
6)選擇連接方式, ORACLE 有三種連接方式,對多表連接 ORACLE 可選擇適當的連接方式。
7)選擇連接順序, 對多表連接 ORACLE 選擇哪一對錶先連接,選擇這兩表中哪個表做爲源數據表。
8)選擇數據的搜索路徑,根據以上條件選擇合適的數據搜索路徑,如是選用全表搜索還是利用索引或是其他的方式。
9)運行“執行計劃”
二、oracle 共享原理:
ORACLE將執行過的SQL語句存放在內存的共享池(shared buffer pool)中,可以被所有的數據庫用戶共享 當你執行一個SQL語句(有時被稱爲一個遊標)時,如果它和之前的執行過的語句完全相同, ORACLE就能很快獲得已經被解析的語句以及最好的 執行路徑. 這個功能大大地提高了SQL的執行性能並節省了內存的使用
三、oracle 語句提高查詢效率的方法:1: wherecolumnin(select*from ... where ...); 2:... whereexists (select'X'from ...where ...); 第二種格式要遠比第一種格式的效率高。在Oracle中可以幾乎將所有的IN操作符子查詢改寫爲使用EXISTS的子查詢 使用EXIST,Oracle系統會首先檢查主查詢,然後運行子查詢直到它找到第一個匹配項,這就節省了時間 Oracle系統在執行IN子查詢時,首先執行子查詢,並將獲得的結果列表存放在在一個加了索引的臨時表中 避免使用having字句 避免使用HAVING子句, HAVING 只會在檢索出所有記錄之後纔對結果集進行過濾. 這個處理需要排序,總計等操作. 如果能通過WHERE子句限制記錄的數目,那就能減少這方面的開銷

SQL Select語句完整的執行順序:

1、from子句組裝來自不同數據源的數據;
2、where子句基於指定的條件對記錄行進行篩選;
3、group by子句將數據劃分爲多個分組;
4、使用聚集函數進行計算;
5、使用having子句篩選分組;
6、計算所有的表達式;
7、使用order by對結果集進行排序
邏輯查詢處理步驟
代碼如下:
Java代碼 複製代碼 收藏代碼
  1. (8)SELECT (9)DISTINCT
  2. (11)<TOP_specification> <select_list>
  3. (1)FROM <left_table>
  4. (3)<join_type> JOIN <right_table>
  5. (2)    ON <join_condition>
  6. (4)WHERE <where_condition>
  7. (5)GROUP BY <group_by_list>
  8. (6)WITH {CUBE ROLLUP}
  9. (7)HAVING <having_condition>
  10. (10)ORDER BY <order_by_list>
(8)SELECT (9)DISTINCT 
(11)<TOP_specification> <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)WITH {CUBE ROLLUP} 
(7)HAVING <having_condition> 
(10)ORDER BY <order_by_list> 


每個步驟產生一個虛擬表,該虛擬表被用作下一個步驟的輸入。只有最後一步生成的表返回給調用者。如
果沒有某一子句,則跳過相應的步驟。
1. FROM:對FROM子句中的前兩個表執行笛卡爾積,生成虛擬表VT1。
2. ON:對VT1應用ON篩選器。只有那些使<join_condition>爲真的行才被插入VT2。
3. OUTER(JOIN):如果指定了OUTER JOIN,保留表中未找到匹配的行將作爲外部行添加到VT2,生成VT3。
如果FROM子句包含兩個以上的表,則對上一個聯接生成的結果表和下一個表重複執行步驟1到步驟3,直到
處理完所有的表爲止。
4. 對VT3應用WHERE篩選器。只有使<where_condition>爲TRUE的行才被插入VT4。
5. GROUP BY:按GROUP BY 子句中的列列表對VT4中的行分組,生成VT5。
6. CUBEROLLUP:把超組插入VT5,生成VT6。
7. HAVING:對VT6應用HAVING篩選器。只有使<having_condition>爲TRUE的組纔會被插入VT7。
8. SELECT:處理SELECT列表,產生VT8。
9. DISTINCT:將重複的行從VT8中移除,產生VT9。
10. ORDER BY:將VT9中的行按ORDER BY子句中的列列表排序,生成一個有表(VC10)。
11. TOP:從VC10的開始處選擇指定數量或比例的行,生成表VT11,並返回給調用者。
以下是其它網友的補充:
好像自已在書寫 SQL 語句時由於不清楚各個關鍵字的執行順序, 往往組織的 SQL 語句缺少很好的邏輯, 憑感覺 "拼湊" ( 不好意思, 如果您的 SQL 語句也經常 "拼湊", 那您是不是得好好反省一下呢?, 呵呵).
這樣做確實是爽了自己, 可苦了機器, 服務器還需要在我們的雜亂無章的 SQL 語句中尋找它下一句需要執行的關鍵字在哪裏.
效率嘛, 由於我們的感覺神經對秒以下的變化實在不敏感, 暫且就認爲自已寫的 SQL 順序無關緊要, "反正沒什麼變化!", 呵呵.其實服務器對每句 SQL 解析時間都會有詳細記錄的, 大家可以看一下自已按習慣寫的 SQL 和按標準順序寫的SQL解析時間差別有多大.
因此, 建議大家在平時工作中 SQL 語句按標準順序寫, 一是專業, 二是實用, 呵呵, 不過我覺得最主要的是心裏感覺舒服.
標準的 SQL 的解析順序爲:
(1).FROM 子句, 組裝來自不同數據源的數據
(2).WHERE 子句, 基於指定的條件對記錄進行篩選
(3).GROUP BY 子句, 將數據劃分爲多個分組
(4).使用聚合函數進行計算
(5).使用 HAVING 子句篩選分組
(6).計算所有的表達式
(7).使用 ORDER BY 對結果集進行排序
舉例說明: 在學生成績表中 (暫記爲 tb_Grade), 把 "考生姓名"內容不爲空的記錄按照 "考生姓名" 分組, 並且篩選分組結果, 選出 "總成績" 大於 600 分的.
標準順序的 SQL 語句爲:
select 考生姓名, max(總成績) as max總成績
from tb_Grade
where 考生姓名 is not null
group by 考生姓名
having max(總成績) > 600
order by max總成績
在上面的示例中 SQL 語句的執行順序如下:
(1). 首先執行 FROM 子句, 從 tb_Grade 表組裝數據源的數據
(2). 執行 WHERE 子句, 篩選 tb_Grade 表中所有數據不爲 NULL 的數據
(3). 執行 GROUP BY 子句, 把 tb_Grade 表按 "學生姓名" 列進行分組
(4). 計算 max() 聚集函數, 按 "總成績" 求出總成績中最大的一些數值
(5). 執行 HAVING 子句, 篩選課程的總成績大於 600 分的.
(7). 執行 ORDER BY 子句, 把最後的結果按 "Max 成績" 進行排序.
好了,看了這些之後,我相信大家都知道了SQL中select語句的執行順序了吧!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章