sql server 创建唯一性非聚集索引语句_数据库专题—索引原理
深入淺出數(shù)據(jù)庫索引原理
參見:https://www.cnblogs.com/aspwebchh/p/6652855.html
1.為什么給表加上主鍵?
- 1.平時創(chuàng)建表的時候,都會給表加上主鍵。如果沒有主鍵的表,數(shù)據(jù)會一行行的排列在磁盤上,查找一個數(shù)據(jù)需要一條條的進(jìn)行對比。而加上主鍵的表,會變成樹形(B樹/B+樹),這樣整個表就變成一個索引,即聚合索引
假如我們執(zhí)行一個SQL語句:
select * from table where id = 1256;
首先根據(jù)索引定位到1256這個值所在的葉結(jié)點,然后再通過葉結(jié)點取到id等于1256的數(shù)據(jù)行。
2.為什么索引后會使查詢變快?
- 假如一張表有一億條數(shù)據(jù) ,需要查找其中某一條數(shù)據(jù),按照常規(guī)邏輯, 一條一條的去匹配的話, 最壞的情況下需要匹配一億次才能得到結(jié)果,用大O標(biāo)記法就是O(n)最壞時間復(fù)雜度,這是無法接受的,而且這一億條數(shù)據(jù)顯然不能一次性讀入內(nèi)存供程序使用, 因此, 這一億次匹配在不經(jīng)緩存優(yōu)化的情況下就是一億次IO開銷,以現(xiàn)在磁盤的IO能力和CPU的運(yùn)算能力, 有可能需要幾個月才能得出結(jié)果 。如果把這張表轉(zhuǎn)換成平衡樹結(jié)構(gòu)(一棵非常茂盛和節(jié)點非常多的樹),假設(shè)這棵樹有10層,那么只需要10次IO開銷就能查找到所需要的數(shù)據(jù), 速度以指數(shù)級別提升,用大O標(biāo)記法就是O(log n),n是記錄總樹,底數(shù)是樹的分叉數(shù),結(jié)果就是樹的層次數(shù)。
3.為什么加索引后會使寫入、修改、刪除變慢?
- 事物都是有兩面的, 索引能讓數(shù)據(jù)庫查詢數(shù)據(jù)的速度上升, 而使寫入數(shù)據(jù)的速度下降,原因很簡單的, 因為平衡樹這個結(jié)構(gòu)必須一直維持在一個正確的狀態(tài), 增刪改數(shù)據(jù)都會改變平衡樹各節(jié)點中的索引數(shù)據(jù)內(nèi)容,破壞樹結(jié)構(gòu), 因此,在每次數(shù)據(jù)改變時, DBMS必須去重新梳理樹(索引)的結(jié)構(gòu)以確保它的正確,這會帶來不小的性能開銷,也就是為什么索引會給查詢以外的操作帶來副作用的原因。
4.什么情況下要同時在兩個字段上建索引?
4.1 非聚合索引
- 非聚集索引和聚集索引一樣, 同樣是采用平衡樹作為索引的數(shù)據(jù)結(jié)構(gòu)。索引樹結(jié)構(gòu)中各節(jié)點的值來自于表中的索引字段, 假如給user表的name字段加上索引 , 那么索引就是由name字段中的值構(gòu)成,在數(shù)據(jù)改變時, DBMS需要一直維護(hù)索引結(jié)構(gòu)的正確性。如果給表中多個字段加上索引 , 那么就會出現(xiàn)多個獨立的索引結(jié)構(gòu),每個索引(非聚集索引)互相之間不存在關(guān)聯(lián)。 如下圖
- 每次給字段建一個新索引, 字段中的數(shù)據(jù)就會被復(fù)制一份出來, 用于生成索引。 因此, 給表添加索引,會增加表的體積, 占用磁盤存儲空間。
非聚集索引和聚集索引的區(qū)別在于, 通過聚集索引可以查到需要查找的數(shù)據(jù), 而通過非聚集索引可以查到記錄對應(yīng)的主鍵值 , 再使用主鍵的值通過聚集索引查找到需要的數(shù)據(jù),如下圖
4.2 覆蓋索引
- 非聚合索引都會利用主鍵通過聚合索引來定位到數(shù)據(jù),聚合索引(主鍵)是通往真實數(shù)據(jù)所在的唯一路徑,但是有一種例外是可以不使用聚合索引就能查詢到所需要的數(shù)據(jù),這種辦法被稱為覆蓋索引。
先看下面這個SQL語句
//建立索引
create index index_birthday on user_info(birthday);
//查詢生日在1991年11月1日出生用戶的用戶名
select user_name from user_info where birthday = '1991-11-1'
這句SQL語句的執(zhí)行過程如下
首先,通過非聚集索引index_birthday查找birthday等于1991-11-1的所有記錄的主鍵ID值
然后,通過得到的主鍵ID值執(zhí)行聚集索引查找,找到主鍵ID值對就的真實數(shù)據(jù)(數(shù)據(jù)行)存儲的位置
最后, 從得到的真實數(shù)據(jù)中取得user_name字段的值返回, 也就是取得最終的結(jié)果
我們把birthday字段上的索引改成雙字段的覆蓋索引
create index index_birthday_and_user_name on user_info(birthday, user_name);
這句SQL語句的執(zhí)行過程就會變?yōu)?/p>
通過非聚集索引index_birthday_and_user_name查找birthday等于1991-11-1的葉節(jié)點的內(nèi)容,然而, 葉節(jié)點中除了有user_name表主鍵ID的值以外, user_name字段的值也在里面, 因此不需要通過主鍵ID值的查找數(shù)據(jù)行的真實所在, 直接取得葉節(jié)點中user_name的值返回即可。 通過這種覆蓋索引直接查找的方式, 可以省略不使用覆蓋索引查找的后面兩個步驟, 大大的提高了查詢性能,如下圖
一、為什么要創(chuàng)建索引呢(優(yōu)點)?
這是因為,創(chuàng)建索引可以大大提高系統(tǒng)的性能。
第一, 通過創(chuàng)建唯一性索引,可以保證數(shù)據(jù)庫表中每一行數(shù)據(jù)的唯一性。
第二, 可以大大加快數(shù)據(jù)的檢索速度,這也是創(chuàng)建索引的最主要的原因。
第三, 可以加速表和表之間的連接,特別是在實現(xiàn)數(shù)據(jù)的參考完整性方面特別有意義。
第四, 在使用分組和排序子句進(jìn)行數(shù)據(jù)檢索時,同樣可以顯著減少查詢中分組和排序的時間。
第五, 通過使用索引,可以在查詢的過程中,使用優(yōu)化隱藏器,提高系統(tǒng)的性能。
二、建立方向索引的不利因素(缺點)
也許會有人要問:增加索引有如此多的優(yōu)點,為什么不對表中的每一個列創(chuàng)建一個索引呢?這種想法固然有其合理性,然而也有其片面性。雖然,索引有許多優(yōu)點,但是,為表中的每一個列都增加索引,是非常不明智的。這是因為,增加索引也有許多不利的一個方面。
第一, 創(chuàng)建索引和維護(hù)索引要耗費(fèi)時間,這種時間隨著數(shù)據(jù)量的增加而增加。
第二, 索引需要占物理空間,除了數(shù)據(jù)表占數(shù)據(jù)空間之外,每一個索引還要占一定的物理空間,如果要建立聚簇索引,那么需要的空間就會更大。
第三, 當(dāng)對表中的數(shù)據(jù)進(jìn)行增加、刪除和修改的時候,索引也要動態(tài)的維護(hù),這樣就降低了數(shù)據(jù)的維護(hù)速度。
三、創(chuàng)建方向索引的準(zhǔn)則
索引是建立在數(shù)據(jù)庫表中的某些列的上面。因此,在創(chuàng)建索引的時候,應(yīng)該仔細(xì)考慮在哪些列上可以創(chuàng)建索引,在哪些列上不能創(chuàng)建索引。
一般來說,應(yīng)該在這些列上創(chuàng)建索引。
第一, 在經(jīng)常需要搜索的列上,可以加快搜索的速度;
第二, 在作為主鍵的列上,強(qiáng)制該列的唯一性和組織表中數(shù)據(jù)的排列結(jié)構(gòu);
第三, 在經(jīng)常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;
第四, 在經(jīng)常需要根據(jù)范圍進(jìn)行搜索的列上創(chuàng)建索引,因為索引已經(jīng)排序,其指定的范圍是連續(xù)的;
第五, 在經(jīng)常需要排序的列上創(chuàng)建索引,因為索引已經(jīng)排序,這樣查詢可以利用索引的排序,加快排序查詢時間;
第六, 在經(jīng)常使用在WHERE子句中的列上面創(chuàng)建索引,加快條件的判斷速度。
同樣,對于有些列不應(yīng)該創(chuàng)建索引。一般來說,不應(yīng)該創(chuàng)建索引的的這些列具有下列特點:
第一, 對于那些在查詢中很少使用或者參考的列不應(yīng)該創(chuàng)建索引。這是因為,既然這些列很少使用到,因此有索引或者無索引,并不能提高查詢速度。相反,由于增加了索引,反而降低了系統(tǒng)的維護(hù)速度和增大了空間需求。
第二, 對于那些只有很少數(shù)據(jù)值的列也不應(yīng)該增加索引。這是因為,由于這些列的取值很少,例如人事表的性別列,在查詢的結(jié)果中,結(jié)果集的數(shù)據(jù)行占了表中數(shù)據(jù)行的很大比例,即需要在表中搜索的數(shù)據(jù)行的比例很大。增加索引,并不能明顯加快檢索速度。
第三, 對于那些定義為text, image和bit數(shù)據(jù)類型的列不應(yīng)該增加索引。這是因為,這些列的數(shù)據(jù)量要么相當(dāng)大,要么取值很少。
第 四, 當(dāng)修改性能遠(yuǎn)遠(yuǎn)大于檢索性能時,不應(yīng)該創(chuàng)建索引。這是因為,修改性能和檢索性能是互相矛盾的。當(dāng)增加索引時,會提高檢索性能,但是會降低修改性能。當(dāng)減少 索引時,會提高修改性能,降低檢索性能。因此,當(dāng)修改性能遠(yuǎn)遠(yuǎn)大于檢索性能時,不應(yīng)該創(chuàng)建索引。
總結(jié)
以上是生活随笔為你收集整理的sql server 创建唯一性非聚集索引语句_数据库专题—索引原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信HOOK 关于转发消息功能开发的一些
- 下一篇: 等压线上怎么画风向_如何利用等压线图判定