【基础】有关T-SQL的10个好习惯
1. 在生產(chǎn)環(huán)境中不要出現(xiàn)Select *
這一點我想大家已經(jīng)是比較熟知了,這樣的錯誤相信會犯的人不會太多。但我這里還是要說一下。
不使用Select *的原因主要不是坊間所流傳的將*解析成具體的列需要產(chǎn)生消耗,這點消耗在我看來完全可以忽略不計。更主要的原因來自以下兩點:
擴展方面的問題
造成額外的書簽查找或是由查找變?yōu)閽呙?/p>
擴展方面的問題是當(dāng)表中添加一個列時,Select *會把這一列也囊括進去,從而造成上面的第二種問題。
而額外的IO這點顯而易見,當(dāng)查找不需要的列時自然會產(chǎn)生不必要的IO,下面我們通過一個非常簡單的例子來比較這兩種差別,如圖1所示。
圖1.*帶來的不必要的IO
2. 聲明變量時指定長度
這一點有時候會被人疏忽,因為對于T-SQL來說,如果對于變量不指定長度,則默認(rèn)的長度會是1??紤]下面這個例子,如圖2所示。
圖2.不指定變量長度有可能導(dǎo)致丟失數(shù)據(jù)
3. 使用合適的數(shù)據(jù)類型
合適的數(shù)據(jù)類型首先是從性能角度考慮,關(guān)于這一點,我寫過一篇文章詳細(xì)的介紹過,有興趣可以閱讀:對于表列數(shù)據(jù)類型選擇的一點思考,這里我就不再細(xì)說了
不要使用字符串類型存儲日期數(shù)據(jù),這一點也需要強調(diào)一些,有時候你可能需要定義自己的日期格式,但這樣做非常不好,不僅是性能上不好,并且內(nèi)置的日期時間函數(shù)也不能用了。
4. 使用Schema前綴來選擇表
解析對象的時候需要更多的步驟,而指定Schema.Table這種方式就避免了這種無謂的解析。
不僅如此,如果不指定Schema容易造成混淆,有時會報錯。
還有一點是,Schema使用的混亂有可能導(dǎo)致更多的執(zhí)行計劃緩存,換句話說,就是同樣一份執(zhí)行計劃被多次緩存,讓我們來看圖3的例子。
圖3.不同的schema選擇不同導(dǎo)致同樣的查詢被多次緩存
5. 命名規(guī)范很重要
推薦使用實體對象+操作這種方式,比如Customer_Update這種方式。在一個大型一點的數(shù)據(jù)庫會存在很多存儲過程,不同的命名方式使得找到需要的存儲過程變得很不方便。因此有可能造成另一種問題,就是重復(fù)創(chuàng)建存儲過程,比如上面這個例子,有可能命名規(guī)范不統(tǒng)一的情況下又創(chuàng)建了一個叫UpdateCustomer的存儲過程。
6. 插入大量數(shù)據(jù)時,盡量不要使用循環(huán),可以使用CTE,如果要使用循環(huán),也放到一個事務(wù)中
這點其實顯而易見。SQL Server是隱式事務(wù)提交的,所以對于每一個循環(huán)中的INSERT,都會作為一個事務(wù)提交。這種效率可想而知,但如果將1000條語句放到一個事務(wù)中提交,效率無疑會提升不少。
打個比方,去銀行存款,是一次存1000效率高,還是存10次100?
7. where條件之后盡量減少使用函數(shù)或數(shù)據(jù)類型轉(zhuǎn)換
換句話說,WHERE條件之后盡量可以使用可以嗅探參數(shù)的方式,比如說盡量少用變量,盡量少用函數(shù),下面我們通過一個簡單的例子來看這之間的差別。如圖4所示。
圖4.在Where中使用不可嗅探的參數(shù)導(dǎo)致的索引查找
對于另外一些情況來說,盡量不要讓參數(shù)進行類型轉(zhuǎn)換,再看一個簡單的例子,我們可以看出在Where中使用隱式轉(zhuǎn)換代價巨大。如圖5所示。
圖5.隱式轉(zhuǎn)換帶來的性能問題
8. 不要使用舊的連接方式,比如(from x,y,z)
可能導(dǎo)致效率底下的笛卡爾積,當(dāng)你看到下面這個圖標(biāo)時,說明查詢分析器無法根據(jù)統(tǒng)計信息估計表中的數(shù)據(jù)結(jié)構(gòu),所以無法使用Loop join, merge Join和Hash Join中的一種,而是使用效率地下的笛卡爾積。
所以,盡量使用Inner join的方式替代from x, y, z這種方式。
9. 使用游標(biāo)時,加上只讀只進選項
首先,我的觀點是:游標(biāo)是邪惡的,盡量少用。但是如果一定要用的話,請記住,默認(rèn)設(shè)置游標(biāo)是可進可退的,如果你僅僅設(shè)置了
declare c cursorfor這樣的形式,那么這種游標(biāo)要慢于下面這種方式。
declare c cursorlocal static read_only forward_onlyfor…所以,在游標(biāo)只讀只進的情況下,加上上面代碼所示的選項。
10. 有關(guān)Order一些要注意的事情
首先,要注意,不要使用Order by+數(shù)字的形式,比如圖6這種。
圖6.Order By序號
當(dāng)表結(jié)構(gòu)或者Select之后的列變化時,這種方式會引起麻煩,所以老老實實寫上列名。
還有一種情況是,對于帶有子查詢和CTE的查詢,子查詢有序并不代表整個查詢有序,除非顯式指定了Order By,讓我們來看圖7。
圖7. 雖然在CTE中中有序,但顯式指定Order By,則不能保證結(jié)果的順序
總結(jié)
以上是生活随笔為你收集整理的【基础】有关T-SQL的10个好习惯的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSS3选择器:nth-child和:n
- 下一篇: mysql batis传多个参数_Myb