什么是聚簇索引與非聚簇索引?

轉(zhuǎn)載:網(wǎng)址:https://www.cnblogs.com/auxg/p/Cluster-and-NonCluster-index.html

今天我們來聊一聊關(guān)于 聚簇索引和非聚簇索引的問題;

剛開始學(xué)數(shù)據(jù)庫SQL的時候里逆,就知道有主鍵啊(Primary-key)娇妓,外鍵啊(Foreign-key)啥的,連個表查詢就已經(jīng)不清楚是要on 那幾個字段了辫塌,在數(shù)據(jù)量不太大的情況下漏策,根本不會考慮索引的問題了,然后臼氨,隨著大數(shù)據(jù)時代的到來掺喻,數(shù)據(jù)量大了,沒有索引那是要不得的啊,客戶又吐槽了感耙,你知不知道褂乍,你知不知道,我等到花兒都謝鳥即硼。逃片。。谦絮。题诵。沒有索引,完全依賴生硬的where條件层皱,達到百萬級數(shù)據(jù)記錄之后性锭,如果沒有主鍵,頁面加載慢的一比叫胖,查詢頁面分分鐘可能被用戶直接關(guān)閉草冈,剩下的你就等著 產(chǎn)品經(jīng)理的一頓又一頓吐槽了吧。瓮增。怎棱。。绷跑。

OK拳恋,閑話不多扯了,言歸正傳砸捏,那我們來了解一下:
(一下僅供新人學(xué)習(xí)交流與個人體會谬运,數(shù)據(jù)庫大神可直接無視,若有不當(dāng)之處垦藏,歡迎大神雅正.)

  • 什么是索引梆暖;
  • 什么是聚簇索引和非聚簇索引;
  • 為什么要建索引;
  • 動手試試,看看代碼怎么敲的掂骏;
  • 性能比較與分析轰驳;

什么是索引.
我們來看看比較大眾的定義,OK,那就直接百度百科吧:"索引是對數(shù)據(jù)庫表中一列或多列的值進行排序的一種結(jié)構(gòu),使用索引可快速訪問數(shù)據(jù)庫表中的特定信息弟灼。" 看中心語-關(guān)鍵詞[一種結(jié)構(gòu)],說到底索引就是對數(shù)據(jù)列的值進行結(jié)構(gòu)化排序的一個東西.

通俗點講吧. 還記得大學(xué)軍訓(xùn)的時候嗎,大伙第一天穿上迷彩服到運動場或者野外軍訓(xùn)場地進行軍訓(xùn)的時候,一般都是亂扎堆的吧,亂成一團,結(jié)果軍訓(xùn)的教官來了,教官一看大伙,有男有女,有高有矮 幾分鐘很快就把大伙排成了m行n列的方針级解,盡然有序,高低有序袜爪;而且沒多久教官還能很快滴說出大家的名字蠕趁,‘x行y列(或者xx號學(xué)員),王大錘辛馆,出列!’ 一聲令下俺陋,王大錘就從隊列中走出來了豁延,...
這段場景中,教官就是軍訓(xùn)場地上最好的【索引】腊状;

什么是聚簇索引和非聚簇索引
有了索引的概念認知诱咏,聚簇索引和非聚簇索引就好理解了,說一個最簡單的例子吧;

【聚簇索引】
平時習(xí)慣逛圖書館的童鞋可能比較清楚缴挖,如果你要去圖書館借一本書袋狞,最開始是去電腦里面查書名然后根據(jù)書名來定位藏書在那個區(qū),哪個書柜映屋,哪一行苟鸯,第多少本。棚点。早处。清晰明確,一目了然瘫析,因為藏書的結(jié)構(gòu)與圖書室的位置砌梆,書架的順序,書本的擺放順序與書籍的編號都是從大到小一致的順序擺放的贬循,所以很容易找到咸包。比如,你的目標藏書在C區(qū)2柜3排5倉杖虾,那么你走到B區(qū)你就很快知道前面就快到了C區(qū)了烂瘫,你直接奔著2柜區(qū)就能找到了。 這就是雷同于聚簇索引的功效了奇适,聚簇索引忱反,實際存儲的順序結(jié)構(gòu)與數(shù)據(jù)存儲的物理機構(gòu)是一致的,所以通常來說物理順序結(jié)構(gòu)只有一種滤愕,那么一個表的聚簇索引也只能有一個,通常默認都是主鍵怜校,設(shè)置了主鍵间影,系統(tǒng)默認就為你加上了聚簇索引,當(dāng)然有人說我不想拿主鍵作為聚簇索引茄茁,我需要用其他字段作為索引魂贬,當(dāng)然這也是可以的,這就需要你在設(shè)置主鍵之前自己手動的先添加上唯一的聚簇索引裙顽,然后再設(shè)置主鍵付燥,這樣就木有問題啦。
總而言之愈犹,聚簇索引是順序結(jié)構(gòu)與數(shù)據(jù)存儲物理結(jié)構(gòu)一致的一種索引键科,并且一個表的聚簇索引只能有唯一的一條闻丑;

【非聚簇索引】
同樣的,如果你去的不是圖書館勋颖,而是某城市的商業(yè)性質(zhì)的圖書城嗦嗡,那么你想找的書就擺放比較隨意了,由于商業(yè)圖書城空間比較緊正饭玲,藏書通常按照藏書上架的先后順序來擺放的侥祭,所以如果查詢到某書籍放在C區(qū)2柜3排5倉,但你可能要繞過F區(qū)茄厘,而不是A.B.C.D...連貫一致的矮冬,也可能同在C區(qū)的2柜,書柜上第一排是計算機類的書記次哈,也可能最后一排就是醫(yī)學(xué)類書籍胎署;

那么對照著來看非聚簇索引的概念就比較好理解了,非聚簇索引記錄的物理順序與數(shù)據(jù)的存儲物理結(jié)構(gòu)沒有關(guān)系亿乳;一個表對應(yīng)的非聚簇索引可以有多條硝拧,根據(jù)不同列的約束可以建立不同要求的非聚簇索引;

為什么要建索引

這個問題肯定很簡單啦葛假,看了上面的描述就知道了障陶,肯定是為了加快找到目標數(shù)據(jù)的速度,節(jié)約查找花費的時間啦聊训,用數(shù)據(jù)庫術(shù)語來描述就是 :
建立索引的目的是加快對表中記錄的查找或排序抱究。
但是話又說回來了,有了索引是不是就以為的數(shù)據(jù)的查詢快得不要不要的带斑,鼓寺。。勋磕。妈候。
或者說,添加了索引之后挂滓,查詢速度一定會比沒有添加索引的情況下更快苦银? 我看未必哦。赶站。幔虏。
我們還是先了解一下 加了索引需要付出的代價和帶來的弊端吧:
一.增加了數(shù)據(jù)庫的存儲空間;
二.在插入和修改數(shù)據(jù)時要花費較多的時間來更新維護索引贝椿;

我們假設(shè)在一張表中的一條記錄在磁盤上占用1KB話想括,我們對其中10B的一個字段建立索引,那么該記錄對應(yīng)的索引塊的大小只有10B烙博,如果一張表的的數(shù)據(jù)量比較大瑟蜈,大約100,000條烟逊,那么用來存儲索引耗費的空間就是100,000X10B=1000,000B=10000KB=1MB,換句話說,這張表也因為這個索引的建立而多使用了大約1MB的存儲空間踪栋,當(dāng)然對與大批量數(shù)據(jù)來說焙格,這么點空間是不足為道的。但事實是夷都,索引確實耗費了更多空間眷唉;

關(guān)于第二條我就不用贅述了,這個文字描述已經(jīng)說的很清楚囤官;
還有就是冬阳,對某些場景下,數(shù)據(jù)量不是特別大的情況下党饮,對于某些添加索引的行為肝陪,不但不能優(yōu)化查詢速度,反而會減慢查詢速度刑顺,當(dāng)然氯窍,如果索引的建立不恰當(dāng),所選擇建立索引的字段不合適蹲堂,也可能會削弱查詢速度狼讨,當(dāng)然在數(shù)據(jù)量不大的情況下,基于SQL服務(wù)器本身強大的處理能力柒竞,這種削弱表現(xiàn)是非常微弱的政供,但是一旦數(shù)據(jù)量大起來,原本可以不需要考慮索引就能很快查詢出來數(shù)據(jù)的,結(jié)果因為添加了索引反而加重了查詢數(shù)據(jù)的消耗朽基,不恰當(dāng)?shù)乃饕绞皆斐傻挠绊懢蜁憩F(xiàn)的很明顯布隔;
所以,索引不是萬能的稼虎,某些情況下衅檀,添加索引可能比不添加索引更慢!

動手試試:看看代碼怎么敲的

建立索引之前選好表對象霎俩,假設(shè)表名為IndexTestTable此表中包含三個字段Id术吝,Name,UniqueCode
為了更快的進行姓名查詢茸苇,我們可以在Name字段上添加非聚簇索引;
創(chuàng)建索引的格式如下:
CREATE NONCLUSTERED INDEX [index_name【索引名稱】] ON table_name【表名稱】;
我們給IndexTestTable表的Name字段添加一個非聚簇索引:
CREATE NONCLUSTERED INDEX IndexTestTable_index_name ON IndexTestTable(Name);
給IndexTestTable表的UniqueCode字段添加一個聚簇索引:
CREATE CLUSTERED INDEX IndexTestTable_index_uniquecode ON IndexTestTable(UniqueCode)
以上的代碼是最簡單最直接設(shè)置索引的方式沦寂,而通常實際應(yīng)用中学密,會有多字段聯(lián)合添加索引的情況,這個就需要你根據(jù)實際的應(yīng)用查詢場景传藏,以及在where條件下最常用的查詢字段腻暮,例如:在 TableX中你最經(jīng)常查詢的條件為:
SELECT Name彤守,Message FROM TableX
WHERE 1=1 AND DeptId='003523'
AND LimitedCondition='SomeValue'
這個時候你就可以 添加一個基于 DeptId 和 LimitedCondition 兩個字段的非聚簇索引,以便于加速查詢速度哭靖;
CREATE NONCLUSTERED INDEX TableX_index_departid_limitedcondition ON TableX(DeptId,LimitedCondition);
簡言之具垫,就是需要根據(jù)你的實際應(yīng)用場景,添加有用并且高效的索引试幽;

性能比較與分析筝蚕;
在一個有千萬級數(shù)據(jù)量的某表mytable中(表沒有實際意義用途,僅限于數(shù)據(jù)查詢研究铺坞,只用三個字段)起宽,查詢數(shù)據(jù)總數(shù),遍歷表記錄耗時大約15秒济榨;
SELECT COUNT(id) FROM mytable;
/* Affected rows: 0 已找到記錄: 1 警告: 0 持續(xù)時間 1 query: 14.750 sec. /
查詢某一行數(shù)據(jù)坯沪,基于主鍵Id查詢,耗時1秒不到擒滑;
SELECT * FROM mytable WHERE id = 7351158;
/
Affected rows: 0 已找到記錄: 1 警告: 0 持續(xù)時間 1 query: 0.031 sec. */

但是同樣是上面 一行數(shù)據(jù) 如果查詢UUID這一種字符型數(shù)據(jù)且未設(shè)置索引的情況下腐晾,則需要耗時較長時間;
SELECT * FROM mytable WHERE xuuid = '0e670e7a-427e-11e6-beb1-286ed48926ad';
/* Affected rows: 0 已找到記錄: 1 警告: 0 持續(xù)時間 1 query: 15.563 sec. */

現(xiàn)在我們在 xuuid上添加一條索引丐一;
CREATE NONCLUSTERED INDEX mytable_index_xuuid ON mytable(xuuid);
好吧 接下來見證奇跡的時候到了藻糖,我們一起來看一下,加完索引之后有什么神奇的變化:
SELECT * FROM mytable WHERE xuuid = '0e670e7a-427e-11e6-beb1-286ed48926ad';
/* Affected rows: 0 已找到記錄: 1 警告: 0 持續(xù)時間 1 query: 0.046 sec. */
看清楚了钝诚, 是0.046秒颖御,換句話說,是46毫秒凝颇;
這樣來說潘拱,數(shù)據(jù)查詢優(yōu)化的空間可是相當(dāng)大有可為的,童鞋們學(xué)好索引的正確打開方式拧略,對以后加快查詢方式會有很大的幫助哦....

最后引用別人[姜敏(http://www.cnblogs.com/aspnet2008/)]曾經(jīng)總結(jié)過的幾句話來描述一下索引的使用原則:
總結(jié)索引使用原則:
1:不要索引數(shù)據(jù)量不大的表芦岂,對于小表來講,表掃描的成本并不高垫蛆。
2:不要設(shè)置過多的索引禽最,在沒有聚集索引的表中,最大可以設(shè)置249個非聚集索引袱饭,過多的索引首先會帶來更大的磁盤空間川无,而且在數(shù)據(jù)發(fā)生修改時,對索引的維護是特別消耗性能的虑乖。
3:合理應(yīng)用復(fù)合索引懦趋,有某些情況下可以考慮創(chuàng)建包含所有輸出列的覆蓋索引。
4:對經(jīng)常使用范圍查詢的字段疹味,可能考慮聚集索引仅叫。
5:避免對不常用的列帜篇,邏輯性列,大字段列創(chuàng)建索引诫咱。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末笙隙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子坎缭,更是在濱河造成了極大的恐慌竟痰,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件幻锁,死亡現(xiàn)場離奇詭異凯亮,居然都是意外死亡,警方通過查閱死者的電腦和手機哄尔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門假消,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人岭接,你說我怎么就攤上這事富拗。” “怎么了鸣戴?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵啃沪,是天一觀的道長。 經(jīng)常有香客問我窄锅,道長创千,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任入偷,我火速辦了婚禮追驴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘疏之。我一直安慰自己殿雪,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布锋爪。 她就那樣靜靜地躺著丙曙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪其骄。 梳的紋絲不亂的頭發(fā)上亏镰,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機與錄音拯爽,去河邊找鬼拆挥。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的纸兔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼否副,長吁一口氣:“原來是場噩夢啊……” “哼汉矿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起备禀,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤洲拇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后曲尸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赋续,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年另患,在試婚紗的時候發(fā)現(xiàn)自己被綠了纽乱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡昆箕,死狀恐怖鸦列,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鹏倘,我是刑警寧澤薯嗤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站纤泵,受9級特大地震影響骆姐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜捏题,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一玻褪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧涉馅,春花似錦归园、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至晤揣,卻和暖如春桥爽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背昧识。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工钠四, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓缀去,卻偏偏與公主長得像侣灶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子缕碎,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354