在SQL Server上该做的和不该做的
?
作為一個使用sqlserver的項目leader,你第一需要知道的是“sqlerver能做什么,不能作什么”。也許數據遷移,也許你遇到數據優化問題不
知道該怎么做,或者您僅僅想知道使用sqlserver的進行數據訪問層的設計指南。這篇文章適合你。
即使你沒有使用sqlserver,絕大多數設計指南也適用其它數據庫管理系統。對程序員來說sybase是一個很熟悉的環境,oracle也能從中受益。
我并不想顯示具體的使用t-sql技巧,也對你的問題給不了神奇的解決方案。這里并沒有完成,或解決的問題。我只想從多年的教訓中學來的經
驗給你一些好的設計建議。發現一遍又一遍出現的設計錯誤。
1.了解你的工具
請不要低估這個建議,它是所有建議中最好的。你驚訝的發現多少程序員并不知道tsql所有的命令和sqlserver都又那些有效的工具。
“什么?我要花費一個月的時間學習一些將來不用的命令?”你可能說no,你不需要。但花費一個周末時間在msdn。瀏覽所有的tsql命令:它能
說什么,不能做什么。在未來,當你設計一個查詢時候,你將記得:“嘿,有個命令能有效完成我們所需要的”。然后你在去參考msdn查看它
的準確語法。
在這里我假定你以及了解了T-SQL語法或者你能在MSDN上找到它。
2.不要使用游標
再次提醒:不要使用游標。它是扼殺整個系統性能的第一途徑。絕大多數初學者使用游標并沒有認識到它對性能的傷害。他們使用大量的內存
,以很怪異的方式鎖表,而且執行速度巨慢。最可惡的是它讓DBA所做的所有優化無效。你知道執行游標和相似的select之間的區別嗎?這意味
著如果你的游標又10000條記錄,它將執行大約10000次select.如果你單獨執行這些select ,update,delete,它將非常塊。
初學者感覺游標是一種熟悉,舒服的編碼方式,不幸的是它導致低下的性能,sql的目的是找出你需要的,而不是它應該怎么做。
有次我重寫一個基于游標的存儲過程,替換了一些傳統的sql查詢,這個表僅10萬條記錄這個存儲過程執行了40分鐘,而事實是最差勁的程序員也
能寫一個執行10秒鐘的存儲過程。
如果你正讀這篇文章,我需要提醒的是這里沒有好的游標使用建議。除了DBA工作的需要,我將不會使用游標。
3.規范化你的表
兩個通常的借口是:性能或延遲。你遲早要為延遲付出代價。如果不慢就不要優化,常常我發現程序員反規范化數據庫。因為他們說這將慢,
然而常常相反。結果這種設計更慢,DBMS被設計來使用規范化數據庫,所以要規范化設計
4.不要使用select *
這個規則執行起來有點難。我承認我常使用它。試著指定你需要的列,他將:
a.減少內存消耗和帶寬
b.容易安全設計
c.可以利用查詢優化,這樣可以從索引中讀取所需的列。
5.了解你的數據怎么被訪問
強健的索引設計是數據庫設計的好方法之一。索引設計常常是很藝術的。每次你在一個表上加一個索引,加快了select,變慢了delete,update.
維護索引需要做很多的事情。如果你給一個表加好幾個索引,你很會就會注意到當更新索引時將鎖很長時間。所以問題是:這個表在干什么?
讀,更新數據?這個問題很巧妙,特別對于update和delete.因為他們常常使用where部分調用一個select,然后才更新表。
6.不要在“性別”列上鍵索引
只是無用的。讓我們理解索引怎么加快表的訪問的。你理解索引快速部分。如果我們建立一個索引在sex列,你將只有兩部分:男女。那你怎么
優化1000萬條記錄呢?記住維護索引是很慢的。一直設計你的索引最多稀少的列先,最少稀少的列最后如:Name + Province + Sex.
7.使用事務:
特別是長時間執行的查詢。當執行錯誤時使用事務將挽救你。當操作數據時候,你將很快發現一下可以讓存儲過程崩潰的異常情況。
8.注意死鎖。
如果你訪問表以相同的順序,當執行存儲過程或事務時,你很快發現死鎖。如果你鎖表A接著鎖表B,一直鎖他們以相同的順序在所有的存儲過程。某天在另外一個存儲過程中,如果你偶然鎖表b接著鎖表A,那么將產生死鎖。死鎖很難被發現。死鎖常是由粗心的設計導致的。
9.不要獲取大記錄
在技術論壇中常看到這樣的提問:“怎么把100000條記錄快速填充到組合框中”。這是個錯誤。你不能也不應該這么做。首先你的用戶討厭在10,000條記錄中找它需要的。看來需要一個好的ui設計。因為你給用戶最多呈現100到200條記錄。
10.使用參數化查詢語句
有時我們在技術類論壇常看到這樣的問題:“我的查詢操作引號等字符時失敗。我怎么能避免它呢”。常見的回答是:“用一個雙引號替換”。錯誤的!這僅是一個工作場景,如果遇到另外一個字符時仍舊失敗。這將導致嚴重的安全bug.除了這個,它將破壞SQL Server緩存系統(緩存相似的查詢)。學怎么使用參數化查詢(在ADO,通過使用Command對象,在ADO.NET使用SqlCommand對象),那么上邊的問題就不會出現。
11. 一直測試大數據庫
通常我們開小數據量的數據上開發,而終端用戶使用大量數據量的數據庫。這里有個問題:磁盤時便宜的而性能問題被發現時已經太遲了。?
12.不要使用insert導入大量數據
如果不是非常必要,請使用DTS或者BCP工具,這是一個既富有擴展性又快速的解決方案。?
13.注意超時:
當查詢數據庫時,缺省超時常很小15秒或30秒。記住查詢報告常比這個常。特別是當數據增長時。??
14.不要忽視并發修改
有時兩個用戶同時修改相同記錄。最后一個修改者修改成功,但前一個用戶的一些更新卻丟失了。檢查這種情況也很容易:產生一個時間戳列,當修改時候檢查它。如果可能的話合并修改。如果有沖突,則提示用戶一些動作。
15.當想詳細表插入記錄時,不要使用從主表中SELECT max(ID)
這是一個常見錯誤。當兩個用戶同時插入數據時將失敗。用SCOPE_IDENTITY, IDENT_CURRENT, and @@IDENTITY其中一個。盡可能避免使用@@IDENTITY。因為使用觸發器可能產生bug.
16.避免使用可空列
他們使用一個多于的字節在每個可空列。當查詢時將產生更多的開銷。DAL也更難編碼。因為每次使用可空列都需要檢查。我并不是說null是邪惡的化身。當空數據是你商業規則的一部分時,我相信他們有好的用法和簡化代碼。一些空列使用在下列情況:
CustomerName1
CustomerAddress1
CustomerEmail1
CustomerName2
CustomerAddress2
CustomerEmail3
CustomerName1
CustomerAddress2
CustomerEmail3
這是糟糕的。經歷避免。請規范化你的,它將更擴展性和快速,減少空列。
17.不要使用TEXT數據類型
除非你為了大數據而使用它。Text數據類型對查詢來說不靈活,慢,而且浪費大量的空間。經常varchar處理數據更好。
18.不要使用臨時表
除非必要。常使用子查詢替換臨時表。它常增加開銷,當運行于COM+給你帶來麻煩。因為它使用數據庫連接池而臨時表將永遠保持。在SQL Server 2000中,表變量可作為可選方案。
19.學會怎么讀執行計劃
SQL Server分析器是你的朋友。你將學會他們怎么工作的。查看查詢,索引怎么影響性能。
20.使用參照完整性
這將為你節省大量時間,定義你所有的鍵,唯一約束,外鍵。
總結
以上是生活随笔為你收集整理的在SQL Server上该做的和不该做的的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tentsqlserver中用bcp 来
- 下一篇: 飞鸽传书下载 分析企业OpenEIM