1. 程式人生 > >SQL查詢原理及執行順序

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: where column in(select*from ... where ...); 2:... where exists (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>   
每個步驟產生一個虛擬表,該虛擬表被用作下一個步驟的輸入。只有最後一步生成的表返回給呼叫者。如 
果沒有某一子句,則跳過相應的步驟。 
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語句的執行順序了吧!