發)有關T-SQL的10個好習慣

來源:互聯網
上載者:User
1.在生產環境中不要出現Select *

     這一點我想大家已經是比較熟知了,這樣的錯誤相信會犯的人不會太多。但我這裡還是要說一下。

     不使用Select *的原因主要不是坊間所流傳的將*解析成具體的列需要產生消耗,這點消耗在我看來完全可以忽略不計。更主要的原因來自以下兩點:

  •      擴充方面的問題
  •      造成額外的書籤尋找或是由尋找變為掃描

     擴充方面的問題是當表中添加一個列時,Select *會把這一列也囊括進去,從而造成上面的第二種問題。

     而額外的IO這點顯而易見,當尋找不需要的列時自然會產生不必要的IO,下面我們通過一個非常簡單的例子來比較這兩種差別,1所示。

   

    圖1.*帶來的不必要的IO

 

2.聲明變數時指定長度

    這一點有時候會被人疏忽,因為對於T-SQL來說,如果對於變數不指定長度,則預設的長度會是1.考慮下面這個例子,2所示。

   

    圖2.不指定變數長度有可能導致遺失資料

 

3.使用合適的資料類型

    合適的資料類型首先是從效能角度考慮,關於這一點,我寫過一篇文章詳細的介紹過,有興趣可以閱讀:對於表列資料類型選擇的一點思考,這裡我就不再細說了

   不要使用字串類型儲存日期資料,這一點也需要強調一些,有時候你可能需要定義自己的日期格式,但這樣做非常不好,不僅是效能上不好,並且內建的日期時間函數也不能用了。

 

4.使用Schema首碼來選擇表

    解析對象的時候需要更多的步驟,而指定Schema.Table這種方式就避免了這種無謂的解析。

    不僅如此,如果不指定Schema容易造成混淆,有時會報錯。

    還有一點是,Schema使用的混亂有可能導致更多的執行計畫緩衝,換句話說,就是同樣一份執行計畫被多次緩衝,讓我們來看圖3的例子。

   

    圖3.不同的schema選擇不同導致同樣的查詢被多次緩衝

 

5.命名規範很重要

    推薦使用實體物件+操作這種方式,比如Customer_Update這種方式。在一個大型一點的資料庫會存在很多預存程序,不同的命名方式使得找到需要的預存程序變得很不方便。因此有可能造成另一種問題,就是重複建立預存程序,比如上面這個例子,有可能命名規範不統一的情況下又建立了一個叫UpdateCustomer的預存程序。

 

6.插入大量資料時,盡量不要使用迴圈,可以使用CTE,如果要使用迴圈,也放到一個事務中

    這點其實顯而易見。SQL Server是隱含交易提交的,所以對於每一個迴圈中的INSERT,都會作為一個事務提交。這種效率可想而知,但如果將1000條語句放到一個事務中提交,效率無疑會提升不少。

    打個比方,去銀行存款,是一次存1000效率高,還是存10次100?

 

7.where條件之後盡量減少使用函數或資料類型轉換

 

   換句話說,WHERE條件之後盡量可以使用可以嗅探參數的方式,比如說盡量少用變數,盡量少用函數,下面我們通過一個簡單的例子來看這之間的差別。4所示。

  

    圖4.在Where中使用不可嗅探的參數導致的索引尋找

 

    對於另外一些情況來說,盡量不要讓參數進行類型轉換,再看一個簡單的例子,我們可以看出在Where中使用隱式轉換代價巨大。5所示。

   

    圖5.隱式轉換帶來的效能問題

 

8.不要使用舊的串連方式,比如(from x,y,z)

    可能導致效率底下的笛卡爾積,當你看到下面這個表徵圖時,說明查詢分析器無法根據統計資訊估計表中的資料結構,所以無法使用Loop join,merge Join和Hash Join中的一種,而是使用效率地下的笛卡爾積。

   

 

    所以,盡量使用Inner join的方式替代from x,y,z這種方式。

 

9.使用遊標時,加上唯讀只進選項

 

    首先,我的觀點是:遊標是邪惡的,盡量少用。但是如果一定要用的話,請記住,預設設定遊標是可進可退的,如果你僅僅設定了

declare c cursorfor

    這樣的形式,那麼這種遊標要慢於下面這種方式。

    
   

 declare c cursorlocal static read_only forward_onlyfor…

 

 

    所以,在遊標唯讀只進的情況下,加上上面代碼所示的選項。

 

10.有關Order一些要注意的事情

    首先,要注意,不要使用Order by+數位形式,比6這種。

   

    圖6.Order By序號

 

    當表結構或者Select之後的列變化時,這種方式會引起麻煩,所以老老實實寫上列名。

 

    還有一種情況是,對於帶有子查詢和CTE的查詢,子查詢有序並不代表整個查詢有序,除非顯式指定了Order By,讓我們來看圖7。

   

    圖7.雖然在CTE中中有序,但顯式指定Order By,則不能保證結果的順序

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.