快消品貨源批發(fā)市場
快消品貨源分銷平臺
 
 
當(dāng)前位置: 貨源批發(fā)網(wǎng) » 網(wǎng)商學(xué)院 » 獨(dú)立商城 » SQL Server 查詢性能優(yōu)化——?jiǎng)?chuàng)建索引原則(一)

SQL Server 查詢性能優(yōu)化——?jiǎng)?chuàng)建索引原則(一)

放大字體  縮小字體 發(fā)布日期:2024-11-20 07:20:16  來源:電商聯(lián)盟  作者:樂發(fā)網(wǎng)  瀏覽次數(shù):5

   索引是什么?索引是提高查詢性能的一個(gè)重要工具,索引就是把查詢語句所需要的少量數(shù)據(jù)添加到索引分頁中,這樣訪問數(shù)據(jù)時(shí)只要訪問少數(shù)索引的分頁就可以。但是索引對于提高查詢性能也不是萬能的,也不是建立越多的索引就越好。索引建少了,用WHERe子句找數(shù)據(jù)效率低,不利于查找數(shù)據(jù)。索引建多了,不利于新增、修改和刪除等操作,因?yàn)樽鲞@些操作時(shí),SQL SERVER除了要更新數(shù)據(jù)表本身,還要連帶地立即更新所有的相關(guān)索引,而且過多的索引也會(huì)浪費(fèi)硬盤空間。因此要建得恰到好處,這就需要經(jīng)驗(yàn)了。
一:索引的基本目的
     索引的基本目的是在大量數(shù)據(jù)中找尋少量數(shù)據(jù)。你可以想像一下,若一本書有700頁,就像數(shù)據(jù)表有700個(gè)數(shù)據(jù)頁,而索引卻有600個(gè)索引頁,你會(huì)想用索引來查詢書籍的內(nèi)容嗎?
     索引字段的值重復(fù)性越低越好,假設(shè)書籍中如“的”“了”這些在文章中重復(fù)性極高的字,每頁都有一大堆,你會(huì)先翻索引頁某個(gè)位置有“的”,翻回該頁讀取了“的”之后,再索引看下一個(gè)“的”,結(jié)果是在先前同一頁的不同位置,又翻回書籍原頁查看下一個(gè)“的”。
     那么怎么理解索引是從大量數(shù)據(jù)中尋找少量數(shù)據(jù)呢?下面我們舉個(gè)例子來說明。
     如果一個(gè)數(shù)據(jù)表的記錄平均長度為400字節(jié),則100萬條記錄需要5萬個(gè)數(shù)據(jù)頁,其計(jì)算公式如下:
  1000000/(8060/400)=50000
  如果該數(shù)據(jù)表建立聚集索引,鍵值為4個(gè)字節(jié)長度,而ID的數(shù)據(jù)長度為13個(gè)字節(jié),因此索引結(jié)構(gòu)每條記錄為20個(gè)字節(jié)。
  4(聚集索引鍵值)+13(ID鍵值)+3(管理信息)=20
  以ID字段所建立的索引,100%填充率,則總分頁數(shù)約為2482頁,其計(jì)算方式如下:
  1000000/(8060/20)
  即使是使用80%的填充率來計(jì)算也只有3106頁。其計(jì)算方式如下:
  1000000/((8060*0.8)/20)
  從上面可以看出如果是第一種情況,則索引頁只占到總數(shù)據(jù)頁的5%:
  2482/50000=0.04964 
  即使考慮取每頁只填充80%的索引數(shù)據(jù),第二種情況,索引頁也只是占總數(shù)據(jù)頁的6%:
  3106/50000=0.06212 
  再說如果查詢條件中的字段建立索引,則由于索引鍵值數(shù)據(jù)都是以B-Tree有順序的擺放,所以可采用二分查找找數(shù)據(jù)。也就是2的N次方大于記錄數(shù),就可以找到該條數(shù)據(jù)。而2的20次方大于100萬,因此最多找尋20次就可以找到該條記錄。由于比較次數(shù)少,數(shù)據(jù)結(jié)構(gòu)也小,節(jié)省訪問硬盤與內(nèi)在的資源,索引將大幅提升找尋數(shù)據(jù)的效率。SQL SERVER為提高訪問與查找對比的效率,用來作索引的數(shù)據(jù)域鍵值愈小愈好,也就是要讓分頁盡量存更多的鍵值記錄。
 注:
  如果未使用 UNIQUE 屬性創(chuàng)建聚集索引,數(shù)據(jù)庫引擎將向表自動(dòng)添加一個(gè) 4 字節(jié)的 uniqueifier 列。必要時(shí),數(shù)據(jù)庫引擎將向行自動(dòng)添加一個(gè) uniqueifier 值以使每個(gè)鍵唯一。此列和列值供內(nèi)部使用,用戶不能查看或訪問。
二:什么是索引
  在 SQL Server 中,索引是按 B 樹結(jié)構(gòu)進(jìn)行組織的。如下圖。
            
  您也可以把索引理解為一種特殊的目錄。微軟的SQL SERVER提供了兩種索引:聚集索引(clustered index,也稱聚類索引、簇集索引)和非聚集索引(nonclustered index,也稱非聚類索引、非簇集索引)。下面,舉例來說明一下聚集索引和非聚集索引的區(qū)別:
  其實(shí),新華字典的正文本身就是一個(gè)聚集索引。比如,我們要查“按”字,就會(huì)很自然地翻開字典的前幾頁,因?yàn)?ldquo;按”的拼音是“an”,而按照拼音排序的新華字典是以英文字母“a”開頭并以“z”結(jié)尾的,那么“按”字就自然地排在字典的前部。如果您翻完了所有以“a”開頭的部分仍然找不到這個(gè)字,那么就說明新華字典中沒有這個(gè)字;同樣的,如果查“招”字,那也會(huì)將新華字典翻到最后部分,因?yàn)?ldquo;招”的拼音是“zhao”。也就是說,新華字典的正文部分本身就是一個(gè)目錄,您不需要再去查其他目錄來找到您需要找的內(nèi)容。我們把這種正文內(nèi)容本身就是一種按照一定規(guī)則排列的目錄稱為“聚集索引”。
  如果您碰到一個(gè)不認(rèn)識的字,不知道它的發(fā)音,這時(shí)候,您就不能按照剛才的方法找到您要查的字,而需要去根據(jù)“偏旁部首”查到您要找的字,然后根據(jù)這個(gè)字后的頁碼直接翻到某頁來找到您要找的字。但您結(jié)合“部首目錄”和“檢字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“張”字,我們可以看到在查部首之后的檢字表中“張”的頁碼是672頁,檢字表中“張”的上面是“馳”字,但頁碼卻是63 頁,“張”的下面是“弩”字,頁面是390頁。很顯然,這些字并不是真正的分別位于“張”字的上下方,現(xiàn)在您看到的連續(xù)的“馳、張、弩”三字實(shí)際上就是他們在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我們可以通過這種方式來找到您所需要的字,但它需要兩個(gè)過程,先找到目錄中的結(jié)果,然后 再翻到您所需要的頁碼。我們把這種目錄純粹是目錄,正文純粹是正文的排序方式稱為“非聚集索引”。
通過以上例子,我們可以理解到什么是“聚集索引”和“非聚集索引”。進(jìn)一步引申一下。
聚集索引
  聚集索引指的是數(shù)據(jù)表本身就是索引的一部分,就是指數(shù)據(jù)表本身就是聚集索引的子葉層,整個(gè)數(shù)據(jù)表的擺放順序是按照你選定的鍵值由小到大排序,SQL SERVER  2000 之后的版本可指定數(shù)據(jù)由大到小排序。
  整個(gè)數(shù)據(jù)表按照鍵值字段由小到大排序,再搭配由鍵值字段加上指針的上層索引結(jié)構(gòu),也就是根節(jié)點(diǎn)和非子葉層級,形成整個(gè)聚集索引。因?yàn)閿?shù)據(jù)表內(nèi)實(shí)際擺放數(shù)據(jù)的方式只能遵循一種順序,所以一個(gè)數(shù)據(jù)表只能有一個(gè)聚集索引。在指定聚集索引時(shí),數(shù)據(jù)域本身并不需要唯一,或指定為唯一的聚集索引,SQL SERVER內(nèi)部會(huì)自動(dòng)為重復(fù)的鍵值建立4個(gè)字節(jié)的唯一標(biāo)識。
  如果你的數(shù)據(jù)表有一列常常用來排序,另一列常常用來 范圍查詢,還有一列重復(fù)性非常高,則該用哪一列來做聚集索引。正確答案是依據(jù)哪個(gè)查詢最重要,最常被用戶執(zhí)行。例如:你的老板一小時(shí)內(nèi)多次執(zhí)行某個(gè)查詢當(dāng)然比一個(gè)月執(zhí)行一兩次的查詢來得重要。 
  表(堆)創(chuàng)建聚集索引或刪除和重新創(chuàng)建現(xiàn)有聚集索引時(shí),要求數(shù)據(jù)庫具有額外的可用工作區(qū)來容納數(shù)據(jù)排序結(jié)果和原始表或現(xiàn)有聚集索引數(shù)據(jù)的臨時(shí)副本。 
  當(dāng)堆或聚集表具有多個(gè)分區(qū)時(shí),每個(gè)分區(qū)都有一個(gè)堆或 B 樹結(jié)構(gòu),其中包含該指定分區(qū)的行組。例如,如果一個(gè)聚集表有 4 個(gè)分區(qū),那么將有 4 個(gè) B 樹,每個(gè)分區(qū)一個(gè)。
  聚集索引( Clustered Index)
  ·        聚集索引的葉節(jié)點(diǎn)就是實(shí)際的數(shù)據(jù)頁
  ·        在數(shù)據(jù)頁中數(shù)據(jù)按照索引順序存儲
  ·        行的物理位置和行在索引中的位置是相同的
  ·        每個(gè)表只能有一個(gè)聚集索引
  ·        聚集索引的平均大小大約為表大小的 5%左右
  要使用索引來更有效地排序查詢數(shù)據(jù),最直接的方式就是在你要排序的字段上建立聚集索引。在建立聚集索引之后,SQL SERVER會(huì)重新組織數(shù)據(jù)頁,讓其中的數(shù)據(jù)行按照聚集索引中鍵值的順序存儲。SQL SERVER不需要在硬盤上的數(shù)據(jù)一定要實(shí)際按照聚集索引排序,但在建立聚集索引時(shí),會(huì)嘗試在邏輯上排序數(shù)據(jù)的同時(shí),也會(huì)在物理上讓數(shù)據(jù)盡可能地排序。在索引子葉層級中的每個(gè)數(shù)據(jù)頁都有一個(gè)指針指向索引分頁的前一頁與后一頁,形成雙向鏈接串行,在內(nèi)部的系統(tǒng)數(shù)據(jù)表包含了各索引子葉層第一個(gè)分頁的地址,為了保證數(shù)據(jù)在邏輯上是依照聚集索引的順序存放的,SQL SERVER 只需要由第一個(gè)分頁開始,并依照其連接串行一個(gè)接著一個(gè)依序?qū)ふ覕?shù)據(jù)即可。如下圖。
         
注:聚集表是有聚集索引的表。
非聚集索引
   非聚集索引是完全獨(dú)立于數(shù)據(jù)表之外的結(jié)構(gòu),所以不會(huì)影響數(shù)據(jù)行的順序,其子葉層包含索引行。每個(gè)索引行包含非聚集鍵值、行定位符和任意包含列或非鍵列。行定位符中存入的數(shù)據(jù)有兩種類型:書簽(BOOKMARK)或聚集索引的鍵值。如果數(shù)據(jù)表上建立了聚集索引,則行定位符中存入的數(shù)據(jù)就是聚集索引的鍵值。如果數(shù)據(jù)表沒有建立聚集索引,則行定位符中存入的數(shù)據(jù)就是書簽,即指向數(shù)據(jù)表中記錄具體位置的ROWID,也就是文檔編號、分頁編號與頁內(nèi)記錄編號(稱之為SOLT編號)所組合成的值。通過該ROWID 在數(shù)據(jù)表內(nèi)獲取數(shù)據(jù)就稱為書簽查找 BOOKMARK LOOKUP。所以,一般通過非聚集索引查找到符合的鍵值后,還會(huì)搭配書簽查找。
  當(dāng)非聚集索引從結(jié)構(gòu)中找到符合的記錄時(shí),雖然在子葉層該鍵值是由小到大排序,因此可能在一個(gè)分頁上就有全部符合查詢條件的鍵值,但因?yàn)閿?shù)據(jù)表中數(shù)據(jù)行的擺放是沒有按順序的(或是說沒有按照該非聚集索引的鍵值順序擺放),所以真正符合記錄的數(shù)據(jù)是散布在文檔各處的,而SQL SERVER每次讀取數(shù)據(jù)都是以數(shù)據(jù)頁為單位,因此,找到一條記錄所在位置后,要先將存放該條記錄的分頁讀到內(nèi)存中,再從該頁讀出記錄。
  因?yàn)锽OOKMARK LOOKUP是進(jìn)行隨機(jī)的I/O操作,當(dāng)符合查詢的記錄很多時(shí),通過非聚集索引訪問將導(dǎo)致數(shù)據(jù)頁讀取非常頻繁,就算兩條記錄在同一個(gè)分頁,該分頁也會(huì)被重復(fù)讀兩次,因此或符合的記錄有N條,就需要讀取數(shù)據(jù)表內(nèi)的分頁N頁,雖然大部分的讀取操作都是針對內(nèi)存中的高速緩存,但記錄數(shù)過多時(shí)一樣沒有效率,還不如數(shù)據(jù)表掃描,全部掃描一遍,把符合條件數(shù)據(jù)找出來。
  雖然 SQL 2005 以后的版本中已經(jīng)不在提 BOOKMARK LOOKUP了(但實(shí)際上卻是換湯不換藥),我們的很多搜索都是使用如下的搜索過程:先在非聚集中找,然后再在聚集索引中找。如下圖。
         
  非聚集索引 ( Unclustered Index)  
  ·        非聚集索引的頁,不是數(shù)據(jù),而是指向數(shù)據(jù)頁的頁。
  ·        若未指定索引類型,則默認(rèn)為非聚集索引
  ·        葉節(jié)點(diǎn)頁的次序和表的物理存儲次序不同
  ·        每個(gè)表最多可以有 249個(gè)非聚集索引(一般認(rèn)為每個(gè)表不應(yīng)該超過10個(gè)索引)
  ·        在非聚集索引創(chuàng)建之前創(chuàng)建聚集索引(否則會(huì)引發(fā)索引重建)
  聚集索引與非聚集索引使用的情況:
 動(dòng)作描述
使用聚集索引 
 使用非聚集索引
 外鍵列
 應(yīng)
 應(yīng)
 主鍵列
 應(yīng)
 應(yīng)
 列經(jīng)常被分組排序(order by)
 應(yīng)
 應(yīng)
 返回某范圍內(nèi)的數(shù)據(jù)
 應(yīng)
 不應(yīng)
 小數(shù)目的不同值
 應(yīng)
 不應(yīng)
 大數(shù)目的不同值
 不應(yīng)
 應(yīng)
 頻繁更新的列
 不應(yīng) 
 應(yīng)
 頻繁修改索引列
 不應(yīng)
 應(yīng)
 一個(gè)或極少不同值
 不應(yīng)
 不應(yīng)
  今天就普及一下索引的一些基本知識,明天來說明怎么選擇要?jiǎng)?chuàng)建索引的列,條件是什么,方法是什么。

樂發(fā)網(wǎng)超市批發(fā)網(wǎng)提供超市貨源信息,超市采購進(jìn)貨渠道。超市進(jìn)貨網(wǎng)提供成都食品批發(fā),日用百貨批發(fā)信息、微信淘寶網(wǎng)店超市采購信息和超市加盟信息.打造國內(nèi)超市采購商與批發(fā)市場供應(yīng)廠商搭建網(wǎng)上批發(fā)市場平臺,是全國批發(fā)市場行業(yè)中電子商務(wù)權(quán)威性網(wǎng)站。

本文內(nèi)容整合網(wǎng)站:百度百科、知乎、淘寶平臺規(guī)則

本文來源: SQL Server 查詢性能優(yōu)化——?jiǎng)?chuàng)建索引原則(一)

分享與收藏:  網(wǎng)商學(xué)院搜索  告訴好友  關(guān)閉窗口  打印本文 本文關(guān)鍵字:
 
更多..資源下載
獨(dú)立商城圖文
獨(dú)立商城網(wǎng)商學(xué)院推薦
獨(dú)立商城點(diǎn)擊排行
 
手機(jī)版 手機(jī)掃描訪問
亚洲一级av,黑白配精品在线视频,欧美亚洲综合网站,高清在线无码不卡69 www.sucaiwu.net