<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      從性能的角度談SQL Server聚集索引鍵的選擇

      簡介

          在SQL Server中,數據是按頁進行存放的。而為表加上聚集索引后,SQL Server對于數據的查找就是按照聚集索引的列作為關鍵字進行了。因此對于聚集索引的選擇對性能的影響就變得十分重要了。本文從旨在從性能的角度來談聚集索引的選擇,但這僅僅是從性能方面考慮。對于有特殊業務要求的表,則需要按實際情況進行選擇。

       

      聚集索引所在的列或列的組合最好是唯一的

          這個原因需要從數據的存放原理來談。在SQL Server中,數據的存放方式并不是以行(Row)為單位,而是以頁為單位。因此,在查找數據時,SQL Server查找的最小單位實際上是頁。也就是說即使你只查找一行很小的數據,SQL Server也會將整個頁查找出來,放到緩沖池中。

          每一個頁的大小是8K。每個頁都會有一個對于SQL Server來說的物理地址。這個地址的寫法是 文件號:頁號(理解文件號需要你對文件和文件組有所了解).比如第一個文件的第50頁。則頁號為1:50。當表沒有聚集索引時,表中的數據頁是以堆(Heap)進行存放的,在頁的基礎上,SQL Server通過一個額外的行號來唯一確定每一行,這也就是傳說中的RID。RID是文件號:頁號:行號來進行表示的,假設這一行在前面所說的頁中的第5行,則RID表示為1:50:5,如圖1所示。

          1

          圖1.RID的示例

        

          從RID的概念來看,RID不僅僅是SQL Server唯一確定每一行的依據,也是存放行的存放位置。當頁通過堆(Heap)進行組織時,頁很少進行移動。

          而當表上建立聚集索引時,表中的頁按照B樹進行組織。此時,SQL Server尋找行不再是按RID進行查找,轉而使用了關鍵字,也就是聚集索引的列作為關鍵字進行查找。假設圖1的表中,我們設置DepartmentID列作為聚集索引列。則B樹的非葉子節點的行中只包含了DepartmentID和指向下一層節點的書簽(BookMark)。

          而當我們創建的聚集索引的值不唯一時,SQL Server則無法僅僅通過聚集索引列(也就是關鍵字)唯一確定一行。此時,為了實現對每一行的唯一區分,則需要SQL Server為相同值的聚集索引列生成一個額外的標識信息進行區分,這也就是所謂的uniquifiers。而使用了uniquifier后,對性能產生的影響分為如下兩部分:

      •     SQL Server必須在插入或者更新時對現在數據進行判斷是否和現有的鍵重復,如果重復,則需要生成uniquifier,這個是一筆額外開銷。
      •     因為需要對相同值的鍵添加額外的uniquifier來區分,因此鍵的大小被額外的增加了。因此無論是葉子節點和非葉子節點,都需要更多的頁進行存儲。從而還影響到了非聚集索引,使得非聚集索引的書簽列變大,從而使得非聚集索引也需要更多的頁進行存儲。

          下面我們進行測試,創建一個測試表,創建聚集索引。插入10萬條測試數據,其中每2條一重復,如圖2所示。

          2

          圖2.插入數據的測試代碼

          

         此時,我們來查看這個表所占的頁數,如圖3所示。

          3

          圖3.插入重復鍵后10萬數據占了359頁

       

          我們再次插入10萬不重復的數據,如圖4所示。

          4

          圖4.插入10萬不重復的建的代碼

       

          此時,所占頁數縮減為335頁,如圖5所示。

          5

          圖5.插入不重復鍵后縮減為335頁

       

           因此,推薦聚集索引所在列使用唯一鍵。

       

      最好使用窄列或窄列組合作為聚集索引列

          這個道理和上面減少頁的原理一樣,窄列使得鍵的大小變小。使得聚集索引的非葉子節點減少,而非聚集索引的書簽變小,從而葉子節點頁變得更少。最終提高了性能。

       

      使用值很少變動的列或列的組合作為聚集索引列

          在前面我們知道。當為表創建聚集索引后。SQL Server按照鍵查找行。因為在B數中,數據是有序的,所以當聚集索引鍵發生改變時,不僅僅需要改變值本身,還需要改變這個鍵所在行的位置(RID),因此有可能使得行從一頁移動到另一頁。從而達到有序。因此會帶來如下問題:

      •     行從一頁移動到另一頁,這個操作是需要開銷的,不僅如此,這個操作還可能影響到其他行,使得其他行也需要移動位置,有可能產生分頁
      •     行在頁之間的移動會產生索引碎片
      •     鍵的改變會影響到非聚集索引,使得非聚集索引的書簽也需要改變,這又是一筆額外的開銷

           這也就是為什么很多表創建一列與數據本身無關的列作為主鍵比如AdventureWorks數據庫中的Person.Address表,使用AddressID這個和數據本身無關的列作為聚集索引列,如圖6所示。而使用AddressLine1作為主鍵的話,員工地址的變動則可能造成上面列表的問題。

          6

          圖6.創建和數據本身無關的一列作為聚集索引列

       

      最好使用自增列作為聚集索引列

          這個建議也同樣推薦創建一個和數據本身無關的自增列作為聚集索引列。我們知道,如果新添加進來的數據如果聚集索引列需要插入當前有序的B樹中,則需要移動其它的行來給新插入的行騰出位置。因此可能會造成分頁和索引碎片。同樣的,還會造成修改非聚集索引的額外負擔。而使用自增列,新行的插入則會大大的減少分頁和碎片。

         最近我碰到過一個情況。一個表每隔幾個月性能就奇慢無比,初步查看是由于有大量的索引碎片。可是每隔幾個月重建一次索引讓我無比厭煩。最終我發現,問題是由于當時設計數據庫的人員將聚集索引建在了GUID上,而GUID是隨機生成的,則可能插入到表的任何位置,從而大大增加了碎片的數量。因此造成上面這種情況。

       

      總結

          本文簡單介紹了SQL Server存儲的原理和應該規避的幾種聚集索引建立情況,但這僅僅是從性能的角度來談聚集索引的選擇。對于聚集索引的選擇,還是需要全面的考慮進行決定。

      posted @ 2012-03-06 11:30  CareySon  閱讀(21892)  評論(56)    收藏  舉報
      主站蜘蛛池模板: 欧美精品高清在线观看| 精品熟女日韩中文十区| 欧美大胆老熟妇乱子伦视频| 亚洲色欲色欲大片www无码| 国产精品区一二三四久久| 欧美在线人视频在线观看| 不卡一区二区国产精品| 亚洲人成人伊人成综合网无码| 免费看男女做好爽好硬视频| 四虎影院176| 日韩精品人妻av一区二区三区| 亚洲欧美自偷自拍视频图片| 一区二区免费高清观看国产丝瓜| 国色天香中文字幕在线视频| 欧美亚洲国产成人一区二区三区| 亚洲高潮喷水无码AV电影| 人妻中文字幕精品一页| 国产粉嫩一区二区三区av| 无码天堂va亚洲va在线va| 国产91小视频在线观看| 爆乳女仆高潮在线观看| 狼色精品人妻在线视频| 波多野结衣视频一区二区| 亚洲人成网站在小说| 国产成年码AV片在线观看| 樱花草视频www日本韩国| 四虎永久免费很黄的视频| 免费看视频的网站| 黑人巨大粗物挺进了少妇| 国产亚洲欧美另类一区二区| 国内精品久久人妻无码不卡| 色悠悠国产在线视频一线| 国产精品成人国产乱| 无码高潮爽到爆的喷水视频app| 97se亚洲国产综合在线| 国产永久免费高清在线观看| 无码专区 人妻系列 在线| 在线精品自拍亚洲第一区| 国产乱人伦真实精品视频| 伊人久在线观看视频| 国产最新AV在线播放不卡|