您好,登錄后才能下訂單哦!
這篇文章給大家介紹SQL SERVER SQL 語句優化的示例分析,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
大部分數據庫的語句的執行都需要SQL優化器和執行器來將SQL語句變成執行計劃,在數據庫中執行。網上有很多什么數據庫語句的軍規12條,還有什么數據庫語句秘籍。但不客氣的來說,里面有很多都是道聽途說,或者是多年前的數據庫引擎做的測試等等。SQL SERVER 在經歷了多次的優化器更新換代,我們現在就使用SQL SERVER 2016 第5代數據庫引擎來做一個測試,驗證一下到底網上那些東西靠譜嗎?
1 不給條件,SQL SERVER 會走全表掃描
的確是的,SQL SERVER 在 3代以前的SQL 優化器應該是走TABLE SCAN,但SQL SERVER 這個 5 代的優化器,到底是否還有全表掃描
謊言一: 不給條件查詢語句走TABLE SCAN -----------SQL SERVER 在不給任何條件的情況下,你只要有主鍵,他都不會走 TABLE SCAN,基本上SQL SERVER 這代的數據庫優化器,能走主鍵的,就一定走主鍵,很少在走TABLE SCAN。
那何時 SQL SERVER 還會走全表掃描,你的表設計時候沒有主鍵,(也叫聚簇索引)會全表掃描,下面表沒有主鍵索引。還是的走TABLE SCAN,可你讓他如何,SQL SERVER 最基本的表設計,你都不懂,不要怪TABLE SCAN 怪你自己把。
謊言二,有空字段,走不了索引。
網上大部分的表設計,都要求表的字段不要為NULL,因為他們說走不了索引,是嗎?
謊言:在某些數據庫的確是這樣的,在SQL SERVER 中如果你用以下的語句去查詢,絕對會走索引。
但這不是你可以以此作為借口,說我可以在查詢的字段的設計中,讓他有NULL值。為什么看下邊
看見了嗎? 又走了主鍵掃描,要放以前又是TABLE_SCAN, 具體為什么
這是一個很簡單的邏輯問題,DBA 應該馬上就明白,不明白 CALL ME 我給解釋。
謊言三, IN 的性能不好,NOT IN 和 IN 的性能差不多。這絕對也是謊言,我們繼續做測試。
通過上面的兩個圖,對比,IN 走了索引,基本上可以等同于 where 條件 = A or 條件 = B or 條件 =C
而NOT IN 則不可以走索引,這邊還是走的主鍵掃描,性能那是差的想當的大。
謊言四,exists 和 IN ,比較 EXISTS 的性能好,這不是謊言,這是真的,到目前為止 SQL SERVER 2016的 EXISTS 的寫法 還是要比 IN 的寫法效率高。當然你的相關索引的建立。
謊言五,SQL SERVER 新的SQL 執行和優化引擎,對NULL 支持良好,字段可以不在設置默認值。從下面的圖看,的確是查詢空值是可以的,可以走索引,沒有問題哦。呵呵 在看下面一個圖
馬上打臉,糟糕的一塌糊涂,別急還有
下面的句子,有的程序員是這樣寫的
select * from [dbo].[CACONTRACT] where [SIGNDEALER] in ( null,'00001I73TDVW0000HAOI')
看上去好像沒有什么問題,這里我們將做一個比較
update [dbo].[CACONTRACT] set SIGNDEALER = null where id = '000000002A0060000U4D'
我們將這一行的 SIGNDEALER 設置為 NULL
然后我們查詢
看一下,好像沒有什么問題,真的沒有問題嗎,出了大問題,看似 IN (NULL) 這樣的寫法沒有問題,實際上是大錯特錯,NULL屬于沒有狀態的值,所以無法用一般的運算符來進行運算,上面的語句必須改為
在看執行計劃,慘不忍睹,結論就是如果你在表設計之初就讓 WHERE 條件存在 NULL ,那你就的好好掂量一下,未來NULL給你帶來的各種麻煩。
謊言 6 ,SQL SERVER 中的 NULL 如果使用 IS NOT NULL ,必然無法走索引。
首先這個是真的,不是謊言,如果你膽敢使用 IS NOT NULL ,SQL SERVER 是絕對使用不了索引的,所以強烈反對 WHERE 條件的字段為NULL 這條是坐實了設計表時的硬性條款。
謊言 7 字段的大小和建立索引沒有關系
我們有一個 category的字段是 VARCHAR(4000), 我們可否建立索引,現實的耳光,啪啪的。 設計字段的時候,你要多少就給多少,那種超量很多的字段,在建立索引的時候,就能打的你找不著北。另外一個很長的字段建立索引本身就有問題,各種數據庫都有自己的辦法解決,當然最根本的還是通過非數據庫的方式來解決這樣的問題 (不在此次討論范圍),卡
謊言 8 用 JOIN 的方式一定比用 子查詢的方式好
在某些環節中,JOIN 的寫法是SQL SERVER 所提倡的,但不是說所有的情況都適合用 JOIN 的方式,能用INNER JOIN 的時候,非要用 LEFT JOIN , 能先縮小范圍的情況下,非要先JOIN 在過濾條件,這些都不是好的SQL 語句的撰寫方法,下面的圖就可以看出,語句寫的不一樣,但執行計劃是一樣的。在復雜的環境,靈活的運用各種SQL 語句的寫法,找到適合的才是最好的方式,而不是要限定一種SQL語句的寫法。
SQL SERVER 2016 第5代的SQL 語句執行器,只要具有最基本的數據庫知識FOR SQL SERVER ,TABLE SCAN 基本不會再出現了,讓TABLE SCAN 給 ORACLE 和 MYSQL 繼續使用好了。
SQL SERVER 2016 中如果你在查詢的時候對某個字段進行null 值的查詢,則會走索引,不會不走索引。
在SQL SERVER 中 EXISTS 和 IN 相比較還是EXISTS 的寫法比IN 的方法要好用,性能要高。
SQL SERVER NULL 盡量不要用,設計表要考慮,尤其WHERE條件中的字段
根據SQL解析的邏輯,撰寫適合的SQL語句,提高性能,而不是盲目相信某種固定的方式撰寫的SQL語句,并固化。
關于SQL SERVER SQL 語句優化的示例分析就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。