6、有關索引的幾個問題數據庫
問題1,是否值得在identity字段上創建彙集索引。答案取決於identity 字段如何在語句中使用。若是你常常根據該字段搜索返回不多的行,那麼在其上創建索引是值得的。反之若是identity字段根本不多在語句中使用,那麼就不該該對其創建任何索引。ide
問題2,一個表應該創建多少索引合適。若是表的80%以上的語句都是讀操做,那麼索引能夠多些。可是不要太多。特別是不要對那些更新頻繁的表其創建不少的索引。不多表有超過5個以上的索引。過多的索引不但增長其佔用的磁盤空間,也增長了SQL Server 維護索引的開銷。性能
問題4:爲何SQL Server 在執行計劃中沒有使用你認爲應該使用的索引?緣由是多樣的。一種緣由是該語句返回的結果超過了表的20%數據,使得SQL Server 認爲scan比seek更有效。大數據
另外一種緣由多是表字段的statistics過時了,不能準確反映數據的分佈狀況。你可使用命令UPDATE STATISTICS tablename with FULLSCAN來更新它。只有同步的準確的statistics才能保證SQL Server 產生正確的執行計劃。過期的老的statistics常會致使SQL Server生成不夠優化的甚至愚蠢的執行計劃。因此若是你的表頻繁更新,而你又以爲和之相關的SQL語句運行緩慢,不妨試試UPDATE STATISTIC with FULLSCAN 語句。優化
你甚至可使用Index hint比較不一樣索引的性能差別。好比對上面script 4提到的兩個索引,能夠這樣比較,排序
select 學生姓名, 入學時間 from tbl1 with (index= idx_年齡入學時間)索引
where ……事務
或者:ip
select 學生姓名, 入學時間 from tbl1 with (index= idx_入學時間年齡)同步
where ……
若是強制使用你的索引後logical reads大大減小,那麼就須要進一步研究爲何SQL Server 不使用正確的索引。注意,不要老是將使用索引等同於好的性能,反之亦然。SQL Server只在索引能提升性能時才使用索引檢索。有時候使用Table scan的性能比使用某個索引反而要好。
問題5、什麼使用匯集索引,何時使用非彙集索引
在SQL Server 中索引有彙集索引和非彙集索引兩種。它們的主要差異是前者的索引葉子就是數據自己,然後者的葉子節點包含的是指向數據的書籤(即數據行號或彙集索引的key)。
在上面的例子中我所有使用非彙集索引,緣由是對一個表而言彙集索引只能有一個,而非彙集索引能夠有多個。若是你把上面例子中的非彙集索引換成彙集索引,效果也是相似的,只是彙集索引沒有Bookmark Lookup操做。何時應該使用匯集索引,何時使用非彙集索引取決於應用程序的訪問模式。個人建議是在那些關鍵的字段上使用匯集索引。一個表通常都須要創建一個彙集索引。對於何時使用匯集索引,SQL Server 2000聯機手冊中有以下描述:
在建立彙集索引以前,應先了解您的數據是如何被訪問的。可考慮將彙集索引用於:
彙集索引不適用於:
這將致使整行移動(由於 SQL Server 必須按物理順序保留行中的數據值)。這一點要特別注意,由於在大數據量事務處理系統中數據是易失的。
來自彙集索引的鍵值由全部非彙集索引做爲查找鍵使用,所以存儲在每一個非彙集索引的葉條目內。
7、結束語
如何使一個性能緩慢的系統運行更快更高效,不但須要總體分析數據庫系統,找出系統的性能瓶頸,更須要優化數據庫系統發出的SQL 語句。一旦找出關鍵的SQL 語句並加與優化,性能問題就會迎刃而解。讀完本文,你應該知道建立索引的關鍵是什麼,以及如何分析SQL語句的執行計劃來建立索引。在優化了索引後大部分數據庫系統的性能都可以獲得不一樣程度的改善,有的系統甚至可以得到好幾倍以上的性能提高。本文並不能解決你在優化SQL語句中碰到的全部問題,但其中討論的內容或技巧對許多性能問題都有必定的參考意義。