轉自:http://blog.csdn.net/feixianxxx/article/details/5524819html
SQL Server 優化性能的幾個方面前端
(一).數據庫的設計mysql
能夠參看最近論壇上出現一個精華帖http://topic.csdn.net/u/20100415/10/a377d835-acbd-4815-8bcb-b367f88ac8b5.html?92227
數據庫設計包含物理設計和邏輯設計:
物理設計上能夠經過使用RAID硬件架構。
簡單說下使用策略:
a.RAID0能夠用在只讀的數據庫數據表,或者是通過複製過來的數據庫上,若是你對數據丟失不敏感的話也可使用,總之這個level下是高性能無冗餘;
b.RAID 5 與RAID1 不一樣之處就是多了奇偶校驗,全部的奇偶校驗的信息會遍及各個磁盤,性能上要比RAID1高些,可是一旦發生磁盤I/O失敗,就會形成性能急劇降低,同時這種方法也在RAID0 與RAID1間折了中,是比較通用的作法。
c.RAID 10 就是RAID0 與 RAID1的組合,它提供了高性能,高可用性,性能上要比RAID5好,特別適合大量寫入的應用程序,可是就是成本比較高不管是多少塊磁盤你都是將損失一半的磁盤存儲sql
邏輯設計上能夠經過使用數據庫的一些組件好比表、約束等,在這裏首先提下文件組的使用。當你經費不足,沒法購買一個完整的RAID系統的時候,你能夠考慮文件組。
文件和文件組體系結構一些小節:http://blog.csdn.net/feixianxxx/archive/2010/01/28/5267290.aspx
它的原理就是多硬盤同時讀取,減小磁盤空間爭奪,提升讀取效率。數據庫
我在這再稍微說幾點:緩存
a.範式和數據表的分割和合並
咱們在設計數據庫的時候通常會追求規範,通常會至少達到3NF.在這以後,也許會由於表中某些常常用於存儲查詢的字段而把它們從表中分割,不然大量用戶同時大量訪問一個熱門表,效率會變差。安全
固然有時候也會進行合併表的設計,這樣能夠用少許的冗餘換來減小過多鏈接的運算。
具體關於這個設計表到什麼程度,是否須要分割和合並都是因業務需求和系統承載力而定的,能夠參看更多這方面的書籍。性能優化
b.主鍵與外鍵
做爲表與表之間的聯繫,最直接的就是經過主外鍵進行聯繫。主鍵對於一個表來講是很是重要的,它能在表中做爲行的惟一標識存在,要求:惟一性,不可爲NULL和最小性及容易獲取。服務器
其中最小性指的是做爲主鍵必定要窄。若是鍵值過大,因爲常常存取,它會讓數據庫系統變得沒有效率,並且它須要維護。通常使用1-4字節的字段做爲主鍵。它在做爲集羣索引時也要保持字段的長度適宜,不然索引過長。網絡
定義了外鍵的約束不須要索引,可是因爲鏈接運算的須要,咱們一般須要在創建完外鍵後手動加上必要的索引。
c.表字段的取捨
儘可能讓你的表字段類型「適可而止」,即在符合通常需求長度的前提下,最多稍微增長長度,不要過多浪費。字段存儲直接體如今頁中。行長越短,一頁就能夠存儲越多的記錄行。
當咱們從硬盤中取數據的時候以頁爲單位,一頁中包含的記錄越多,表明放入緩存區的記錄就越多,吞吐量就越大。
1.若是字段的內容比較固定 好比性別 身份證號碼 手機號碼等 就是用定長的 char 或者nchar
2.若是字段的內容變化幅度比較大 則介意使用 varchar或者nvarchar
3.通常不要讓字段能夠爲NULL,這樣會帶來一些處理上沒必要要的消耗,可使用默認值代替它
4.儘量的使用約束來維護數據完整性,不要過度依賴觸發器或者存儲過程來維護,切忌有些簡單的記錄規則不要用前端程序代碼判斷。
5.大型字段如nvarchar(max),char(max),binary(max),text等字段應該切割到獨立表,並用主鍵跟原本的源表相互關聯,由於這些數據類型會形成訪問的緩慢,修改等操做的鎖定,而咱們在查詢的時候又用不到這些字段通常
6.表字段不要太多,通常一行的長度不要過長,這樣會引發每頁存儲的記錄太少,有必要的時候能夠切割有些字段,將一個表分紅2表 甚至更多表存儲。
d.平常維護計劃安排
數據維護計劃,好比備份,重建索引,複製數據等批處理消耗資源的操做盡可能在系統空閒的時候進行。
e.前端程序對基礎表的存取
儘可能讓程序經過據庫中的存儲過程,視圖,函數來存取數據,不要讓其直接在基礎表上進行操做。
f.將在線分析和在線事務的訪問分開
2者的區別很大,具體能夠參考MSDN。簡單來講前者適合查詢,後者多用於插入更新刪除以及部分查詢。
g.作好歸檔的計劃
將什麼歸檔 歸檔週期是什麼 歸檔後如何抽取查詢 歸檔的安全性等問題都須要考慮。
(二).數據庫查詢的優化(T-SQL優化)
這個內容太大了,就挑着點來講
1.儘可能多的使用查詢參數(SARG)
它的通常格式:字段 部分的運算符 《常數或者變量》
這裏的部分運算符包括:= > < >= <= BETWEEN AND 還有LIKE 後面不是以%開頭的。
非SARG的語法,索引通常不起做用。下面列舉一些違反SARG語法的作法:
a.對數據字段進行了運算
我直接舉例子(測試過的): where col_1+col_2='ab' 是不能夠用到索引的 ;
where col1='a' adn col_2='b'則能夠用到字段上的索引;
where col_3+1=4 不能夠用到;where col_3=4-1 能夠用到
b.不要對字段使用逆運算符
不要對字段使用某些逆運算符,好比 not in not like (2000的書上說<> != !>等也是會屏蔽索引的 我在08上是可使用索引的 歡迎有2000環境的朋友測試)
例子(測試過的):where id not like '1%' 或者where id not in(1,2,3) 都是不能用到索引的
c.不要對字段使用函數
使用好比 substring left datediff 等等函數 可是你能夠巧妙的用SARG方式來替代某些函數的功能
好比 left(col,2)='av' 能夠用 col like 'av%' 或者 abs(col-1)>100 能夠用 col>101 or col<-99
d.不要使用OR運算符
使用了OR運算符,多個條件中的字段只要有一個沒有合適的索引,其餘字段的索引都失去索引效果,都將整表掃描。(注意索引掃描和表掃描效率差很少)
可是注意在where中使用非SARG也不必定就用不到索引。有時候包含非SARG的條件 可是仍是會對SARG部分進行索引利用的。
2.表之間的聯接
參考:http://blog.csdn.net/happyflystone/archive/2009/01/15/3786158.aspx
3.大量數據插入
a.在進行大容量數據插入的時候,能夠經過BCP BULK INSERT選項儘可能屏蔽表上的觸發器、約束,甚至刪除表上索引,這樣可讓插入操做快不少。
若是你擔憂數據的不規則,能夠先將數據導入到一個臨時表,而後再數據庫裏面過濾掉不規則數據後,再次由臨時表插入目標表。
b.一樣的大容量插入,推薦使用BULK INSERT。由於一般狀況下,它比BCP要快。
c.使用BCP 或者 BULK INSERT插入時候,採用表鎖定而不是默認的記錄鎖。
d.如服務器多核,能夠儘可能讓多客戶端並行對錶插入。
e.若是插入的數據須要轉換,不要使用DTS等工具直接對記錄的轉化,可使用先插入臨時表,在臨時表內轉化後進行第二次導入。
4.一些其餘注意事項
1.進行少進行排序操做。DISTINCT、Order By、Union 等關鍵詞 只能在須要的時候才用;
2.大批處理數據時,沒有LOG操做必定比逐條且經由2此寫入的動做快。SELECT INTO 比 INSERT SELECT 快,TRUNCATE TABLE 比DELETE TABLE(不含WHERE )快;
3.在05及以上的版本引用數據庫對象時,最好使用兩節名稱格式。由於SQL SERVER對單節名稱對象首先在當前用戶的默認架構下尋找對象名字,若是找不到,再去DBO下尋找。
4.注意聯接操做和子查詢操做的選擇。有時候2者的結果同樣,雖然語句結構不同,可是產生的執行計劃是同樣的。固然,更多時候會出現不一致的執行計劃,儘管結果是相同的,因此要注意不一樣語句的調試;
5.查詢提示:注意,通常狀況下,不須要使用HINT進行查詢,由於會致使優化器不對查詢進行優化;通常的HINT只會用於測試瞭解一些查詢方式,索引,鎖用法對查詢的影響;
(三)索引的合理設計
這又是很大的一塊內容,也不是三言兩語能說完的,介於內容的量和本人水平以及實踐太少,就稍微寫點:
設計索引的準備工做:
1.瞭解數據庫的性質。看它是OLTP仍是OLAP。若是是前者,因爲頻繁修改數據,索引創建索引要謹慎;對於後者,能夠創建不少索引,以加快搜索速度;
2.瞭解哪些查詢是經常使用的查詢;
3.瞭解索引的選項,從這個點提升索引性能;
4.肯定索引存儲位置:如將非彙集索引和數據存放於不一樣磁盤有利於提升性能
創建索引的一些準則:
1.對於常常變更的表,即常常進行插入、更新和刪除操做的表,不能創建太多的索引;反之,則能夠創建比較多的索引,這樣有利於查詢優化器的選擇;
2.索引列務必儘可能保持較小的寬度;
3.對於小型表,即含數據量比較少的表,能夠不創建索引,由於索引的使用有時候還不如進行表掃描來的快;
4.當視圖包含聚合運算,大型錶鏈接的時候可使用索引視圖來顯著提升性能,注意這裏的表不能常常變動;
4.選擇重複性少的列作索引列,重複性大的列 好比性別列這樣的列不如不建索引;
5.使用合理的填充因子;
6.爲常常用於查詢中的謂詞和鏈接條件的和分組的排序的列加上索引;
7.組合索引(覆蓋索引),即由多個列組成的索引,當查詢所須要的列都包含其中的時候能夠顯著提升性能,由於它只須要索引頁的內容就夠了。咱們要注意在這些索引列中
要將常用的列放在儘可能靠前,列的排序爲從最不重複道最重複的列;這裏還有一個索引叫包含性列索引,它是一個特殊的非彙集索引,它能夠包含一些非鍵
列,將這些列加到索引頁的葉級別,這一樣能夠在查詢所須要的列都包含其中的時候能夠顯著提升性能,這2種列 合成爲 多列索引;
我提供幾篇關於索引的文章:
http://www.cnblogs.com/bhtfg538/(裏面有幾篇)
http://hi.baidu.com/dusongw/blog/item/4090493d6ec0cdee3d6d97a6.html
(四)前端應用程序設計
應用程序做爲數據的控制使用端,它將決定什麼時候使用數據,如何使用數據,得來的數據結果又如何處理。它將直接影響服務器端的活動,對整個性能很是關鍵。
下面說幾點應用程序設計的注意點:
1.減小網絡流量
你能夠經過使用存儲過程,甚至可使用 SET NOCOUNT 設置來禁用一些影響行數。還有就是要儘量少的返回數據量,什麼意思呢?就是說,若是你的程序只須要表
中的某些數據,你就不要返回整個表的數據,而後再篩選,直接經過條件在服務器篩選好後再傳過來。
2.限定鎖定超時
不要讓你的查詢無限運行,應該用適當的API設置查詢超時。
3.直到必要的時候才使用遊標
4.事務要儘量的短
5.確保將應用程序設計爲可避免死鎖。
(五)其餘的一些措施:
1.優化服務器性能
服務器配置選項通常都會有默認的自動調整,你能夠經過實際狀況,在肯定有利於你的系統優化的前提下修改某些選項。
好比能夠修改如下幾個方面:
SQL Server 內存;I/0子系統;Windows Server選項。
2.強化硬件設備
加內存、加硬盤容量、升級RAID等等
3.設計聯合數據庫服務器
對於大型的系統,每每須要多個服務器平衡各層的處理負荷。
推薦:海爺寫的SQL SERVER性能優化綜述http://blog.csdn.net/Haiwer/archive/2008/08/25/2826881.aspx
本文參考:性能調優(胡百敬)