SQLServer中SELECT語句的執(zhí)行順序
更新時(shí)間:2010年06月09日 19:09:52 作者:
關(guān)于Sql中Select語句的執(zhí)行順序,一直很少注意這個(gè)問題,對(duì)于關(guān)鍵字的使用也很隨意,至于效率問題,因?yàn)楸碇械臄?shù)據(jù)量都不是很大,所以也不是很在意。
今天在寫一條語句的時(shí)候,在查詢分析器里邊執(zhí)行
要用10s,換用另外一種寫法只用少于1s的時(shí)間,同事說是因?yàn)镾ql句語執(zhí)行順序的原因。之前看過一點(diǎn)相
關(guān)的書,有一點(diǎn)印象,到網(wǎng)上找了資料,學(xué)習(xí)下。
邏輯查詢處理步驟
(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>
每個(gè)步驟產(chǎn)生一個(gè)虛擬表,該虛擬表被用作下一個(gè)步驟的輸入。只有最后一步生成的表返回給調(diào)用者。如
果沒有某一子句,則跳過相應(yīng)的步驟。
1. FROM:對(duì)FROM子句中的前兩個(gè)表執(zhí)行笛卡爾積,生成虛擬表VT1。
2. ON:對(duì)VT1應(yīng)用ON篩選器。只有那些使<join_condition>為真的行才被插入VT2。
3. OUTER(JOIN):如果指定了OUTER JOIN,保留表中未找到匹配的行將作為外部行添加到VT2,生成VT3。
如果FROM子句包含兩個(gè)以上的表,則對(duì)上一個(gè)聯(lián)接生成的結(jié)果表和下一個(gè)表重復(fù)執(zhí)行步驟1到步驟3,直到
處理完所有的表為止。
4. 對(duì)VT3應(yīng)用WHERE篩選器。只有使<where_condition>為TRUE的行才被插入VT4。
5. GROUP BY:按GROUP BY 子句中的列列表對(duì)VT4中的行分組,生成VT5。
6. CUBE|ROLLUP:把超組插入VT5,生成VT6。
7. HAVING:對(duì)VT6應(yīng)用HAVING篩選器。只有使<having_condition>為TRUE的組才會(huì)被插入VT7。
8. SELECT:處理SELECT列表,產(chǎn)生VT8。
9. DISTINCT:將重復(fù)的行從VT8中移除,產(chǎn)生VT9。
10. ORDER BY:將VT9中的行按ORDER BY子句中的列列表排序,生成一個(gè)有表(VC10)。
11. TOP:從VC10的開始處選擇指定數(shù)量或比例的行,生成表VT11,并返回給調(diào)用者。
以下是其它網(wǎng)友的補(bǔ)充:
好像自已在書寫 SQL 語句時(shí)由于不清楚各個(gè)關(guān)鍵字的執(zhí)行順序, 往往組織的 SQL 語句缺少很好的邏輯, 憑感覺 "拼湊" ( 不好意思, 如果您的 SQL 語句也經(jīng)常 "拼湊", 那您是不是得好好反省一下呢?, 呵呵).
這樣做確實(shí)是爽了自己, 可苦了機(jī)器, 服務(wù)器還需要在我們的雜亂無章的 SQL 語句中尋找它下一句需要執(zhí)行的關(guān)鍵字在哪里.
效率嘛, 由于我們的感覺神經(jīng)對(duì)秒以下的變化實(shí)在不敏感, 暫且就認(rèn)為自已寫的 SQL 順序無關(guān)緊要, "反正沒什么變化!", 呵呵.其實(shí)服務(wù)器對(duì)每句 SQL 解析時(shí)間都會(huì)有詳細(xì)記錄的, 大家可以看一下自已按習(xí)慣寫的 SQL 和按標(biāo)準(zhǔn)順序?qū)懙腟QL解析時(shí)間差別有多大.
因此, 建議大家在平時(shí)工作中 SQL 語句按標(biāo)準(zhǔn)順序?qū)? 一是專業(yè), 二是實(shí)用, 呵呵, 不過我覺得最主要的是心里感覺舒服.
標(biāo)準(zhǔn)的 SQL 的解析順序?yàn)?
(1).FROM 子句, 組裝來自不同數(shù)據(jù)源的數(shù)據(jù)
(2).WHERE 子句, 基于指定的條件對(duì)記錄進(jìn)行篩選
(3).GROUP BY 子句, 將數(shù)據(jù)劃分為多個(gè)分組
(4).使用聚合函數(shù)進(jìn)行計(jì)算
(5).使用 HAVING 子句篩選分組
(6).計(jì)算所有的表達(dá)式
(7).使用 ORDER BY 對(duì)結(jié)果集進(jìn)行排序
舉例說明: 在學(xué)生成績(jī)表中 (暫記為 tb_Grade), 把 "考生姓名"內(nèi)容不為空的記錄按照 "考生姓名" 分組, 并且篩選分組結(jié)果, 選出 "總成績(jī)" 大于 600 分的.
標(biāo)準(zhǔn)順序的 SQL 語句為:
select 考生姓名, max(總成績(jī)) as max總成績(jī)
from tb_Grade
where 考生姓名 is not null
group by 考生姓名
having max(總成績(jī)) > 600
order by max總成績(jī)
在上面的示例中 SQL 語句的執(zhí)行順序如下:
(1). 首先執(zhí)行 FROM 子句, 從 tb_Grade 表組裝數(shù)據(jù)源的數(shù)據(jù)
(2). 執(zhí)行 WHERE 子句, 篩選 tb_Grade 表中所有數(shù)據(jù)不為 NULL 的數(shù)據(jù)
(3). 執(zhí)行 GROUP BY 子句, 把 tb_Grade 表按 "學(xué)生姓名" 列進(jìn)行分組
(4). 計(jì)算 max() 聚集函數(shù), 按 "總成績(jī)" 求出總成績(jī)中最大的一些數(shù)值
(5). 執(zhí)行 HAVING 子句, 篩選課程的總成績(jī)大于 600 分的.
(7). 執(zhí)行 ORDER BY 子句, 把最后的結(jié)果按 "Max 成績(jī)" 進(jìn)行排序.
好了,看了這些之后,我相信大家都知道了SQL中select語句的執(zhí)行順序了吧!哈哈!
要用10s,換用另外一種寫法只用少于1s的時(shí)間,同事說是因?yàn)镾ql句語執(zhí)行順序的原因。之前看過一點(diǎn)相
關(guān)的書,有一點(diǎn)印象,到網(wǎng)上找了資料,學(xué)習(xí)下。
邏輯查詢處理步驟
復(fù)制代碼 代碼如下:
(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>
每個(gè)步驟產(chǎn)生一個(gè)虛擬表,該虛擬表被用作下一個(gè)步驟的輸入。只有最后一步生成的表返回給調(diào)用者。如
果沒有某一子句,則跳過相應(yīng)的步驟。
1. FROM:對(duì)FROM子句中的前兩個(gè)表執(zhí)行笛卡爾積,生成虛擬表VT1。
2. ON:對(duì)VT1應(yīng)用ON篩選器。只有那些使<join_condition>為真的行才被插入VT2。
3. OUTER(JOIN):如果指定了OUTER JOIN,保留表中未找到匹配的行將作為外部行添加到VT2,生成VT3。
如果FROM子句包含兩個(gè)以上的表,則對(duì)上一個(gè)聯(lián)接生成的結(jié)果表和下一個(gè)表重復(fù)執(zhí)行步驟1到步驟3,直到
處理完所有的表為止。
4. 對(duì)VT3應(yīng)用WHERE篩選器。只有使<where_condition>為TRUE的行才被插入VT4。
5. GROUP BY:按GROUP BY 子句中的列列表對(duì)VT4中的行分組,生成VT5。
6. CUBE|ROLLUP:把超組插入VT5,生成VT6。
7. HAVING:對(duì)VT6應(yīng)用HAVING篩選器。只有使<having_condition>為TRUE的組才會(huì)被插入VT7。
8. SELECT:處理SELECT列表,產(chǎn)生VT8。
9. DISTINCT:將重復(fù)的行從VT8中移除,產(chǎn)生VT9。
10. ORDER BY:將VT9中的行按ORDER BY子句中的列列表排序,生成一個(gè)有表(VC10)。
11. TOP:從VC10的開始處選擇指定數(shù)量或比例的行,生成表VT11,并返回給調(diào)用者。
以下是其它網(wǎng)友的補(bǔ)充:
好像自已在書寫 SQL 語句時(shí)由于不清楚各個(gè)關(guān)鍵字的執(zhí)行順序, 往往組織的 SQL 語句缺少很好的邏輯, 憑感覺 "拼湊" ( 不好意思, 如果您的 SQL 語句也經(jīng)常 "拼湊", 那您是不是得好好反省一下呢?, 呵呵).
這樣做確實(shí)是爽了自己, 可苦了機(jī)器, 服務(wù)器還需要在我們的雜亂無章的 SQL 語句中尋找它下一句需要執(zhí)行的關(guān)鍵字在哪里.
效率嘛, 由于我們的感覺神經(jīng)對(duì)秒以下的變化實(shí)在不敏感, 暫且就認(rèn)為自已寫的 SQL 順序無關(guān)緊要, "反正沒什么變化!", 呵呵.其實(shí)服務(wù)器對(duì)每句 SQL 解析時(shí)間都會(huì)有詳細(xì)記錄的, 大家可以看一下自已按習(xí)慣寫的 SQL 和按標(biāo)準(zhǔn)順序?qū)懙腟QL解析時(shí)間差別有多大.
因此, 建議大家在平時(shí)工作中 SQL 語句按標(biāo)準(zhǔn)順序?qū)? 一是專業(yè), 二是實(shí)用, 呵呵, 不過我覺得最主要的是心里感覺舒服.
標(biāo)準(zhǔn)的 SQL 的解析順序?yàn)?
(1).FROM 子句, 組裝來自不同數(shù)據(jù)源的數(shù)據(jù)
(2).WHERE 子句, 基于指定的條件對(duì)記錄進(jìn)行篩選
(3).GROUP BY 子句, 將數(shù)據(jù)劃分為多個(gè)分組
(4).使用聚合函數(shù)進(jìn)行計(jì)算
(5).使用 HAVING 子句篩選分組
(6).計(jì)算所有的表達(dá)式
(7).使用 ORDER BY 對(duì)結(jié)果集進(jìn)行排序
舉例說明: 在學(xué)生成績(jī)表中 (暫記為 tb_Grade), 把 "考生姓名"內(nèi)容不為空的記錄按照 "考生姓名" 分組, 并且篩選分組結(jié)果, 選出 "總成績(jī)" 大于 600 分的.
標(biāo)準(zhǔn)順序的 SQL 語句為:
select 考生姓名, max(總成績(jī)) as max總成績(jī)
from tb_Grade
where 考生姓名 is not null
group by 考生姓名
having max(總成績(jī)) > 600
order by max總成績(jī)
在上面的示例中 SQL 語句的執(zhí)行順序如下:
(1). 首先執(zhí)行 FROM 子句, 從 tb_Grade 表組裝數(shù)據(jù)源的數(shù)據(jù)
(2). 執(zhí)行 WHERE 子句, 篩選 tb_Grade 表中所有數(shù)據(jù)不為 NULL 的數(shù)據(jù)
(3). 執(zhí)行 GROUP BY 子句, 把 tb_Grade 表按 "學(xué)生姓名" 列進(jìn)行分組
(4). 計(jì)算 max() 聚集函數(shù), 按 "總成績(jī)" 求出總成績(jī)中最大的一些數(shù)值
(5). 執(zhí)行 HAVING 子句, 篩選課程的總成績(jī)大于 600 分的.
(7). 執(zhí)行 ORDER BY 子句, 把最后的結(jié)果按 "Max 成績(jī)" 進(jìn)行排序.
好了,看了這些之后,我相信大家都知道了SQL中select語句的執(zhí)行順序了吧!哈哈!
相關(guān)文章
hive中將string數(shù)據(jù)轉(zhuǎn)為bigint的操作
這篇文章主要介紹了hive中將string數(shù)據(jù)轉(zhuǎn)為bigint的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-09-09
基于Microsoft SQL Server實(shí)現(xiàn)編寫漢字轉(zhuǎn)拼音函數(shù)
在搜索應(yīng)用中,我們一般會(huì)提供一個(gè)搜索框,輸入關(guān)健字,點(diǎn)擊查詢按鈕以獲取結(jié)果數(shù)據(jù),大部分情況我們會(huì)提供模糊查詢的形式以在一個(gè)或多個(gè)字段進(jìn)行搜索以獲取結(jié)果,本文給大家就介紹了基于Microsoft SQL Server實(shí)現(xiàn)編寫漢字轉(zhuǎn)拼音函數(shù),需要的朋友可以參考下2024-03-03
REPLICATE 以指定的次數(shù)重復(fù)字符表達(dá)式
sql server以指定的次數(shù)重復(fù)字符表達(dá)式REPLICATE函數(shù):REPLICATE函數(shù)用于以指定的次數(shù)重復(fù)字符表達(dá)式。2010-06-06
SQL Server數(shù)據(jù)庫bcp導(dǎo)出備份文件應(yīng)用示例
本節(jié)主要介紹了SQL Server數(shù)據(jù)庫bcp導(dǎo)出備份文件應(yīng)用,需要的朋友可以參考下2014-08-08
SQL server 2019數(shù)據(jù)庫安裝教程詳解
SQL Server 是Microsoft?公司推出的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),具有使用方便可伸縮性好與相關(guān)軟件集成程度高等優(yōu)點(diǎn),Microsoft SQL Server?數(shù)據(jù)庫引擎為關(guān)系型數(shù)據(jù)和結(jié)構(gòu)化數(shù)據(jù)提供了更安全可靠的存儲(chǔ)功能,本章教程,介紹一下SQL Server 2019的安裝過程2024-09-09
實(shí)例理解SQL中truncate和delete的區(qū)別
這篇文章主要介紹了實(shí)例理解SQL中truncate和delete的區(qū)別,truncate和delete兩者易混,本文就為大家進(jìn)行區(qū)分兩者的異同,感興趣的小伙伴們可以參考一下2016-02-02

