資料庫索引(聚集與非聚集)

2021-09-26 13:56:26 字數 2869 閱讀 5182

mysql官方對索引的定義為:索引(index)是幫助mysql高效獲取資料的資料結構;索引是用來對資料表中的乙個列或多個列進行排序的資料結構,在這裡資料庫用的平衡樹,b-tree和b+tree 平衡多路查詢樹

例如:

select * from table1 where id=10000
如果沒有索引,那麼必須遍歷整個表,直到找到id為10000的這一行資料為止;有了索引之後則可直接通過索引來查詢

索引型別:

mysql中索引型別主要分為 聚集索引、 非聚集索引兩種

聚集索引:是對磁碟上實際資料重新組織以按指定的乙個或多個列的值排序的演算法,聚集索引儲存記錄是物理上連續存在,乙個表中只能有乙個聚集索引,因為物理儲存只能有乙個順序

非聚集索引:非聚集索引則是邏輯上連續存在,但是物理上不連續;但是非聚集索引乙個表可以有多個,同時資料庫索引建立預設時非聚集索引

當乙個表沒有加主鍵(聚集索引)的時候,它的資料是無序的放置在磁碟儲存器上,一行一行的排列的很整齊,跟我們認知的表很接近;但給表加上了主鍵之後,就相當於在表中建立了聚集索引,因為主鍵索引一般都是聚集索引(sql server預設主鍵為聚集索引,而mysql主鍵就是聚集索引),那麼表在磁碟上的儲存結構就變成了樹狀結構

非聚集索引的二次查詢問題:

聚集索引索引的葉子節點就是對應的資料節點,可以直接獲取到資料到對應的資料,而非聚集索引在索引處沒有覆蓋到對應的列,它指向的仍是乙個索引節點,只是乙個指標指向對應的資料塊,也就是主鍵的意思,所以非聚集索引查詢出來的值只能得到主鍵id,要得到具體資料要在根據得到的主鍵id通過聚集索引進行查詢,找到主鍵id對應的資料行儲存的位置得到最終結果。

建立表user_inf:

user_id

user_name

user_birthday1張三

1997-1-12李四

1995-2-23王五

1998-3-3

user_id為主鍵,即聚集索引, user_name為非聚集索引

create index index_birthday on user_inf(user_birthday);
執行

select user_name from user_inf where user_birthday = '1997-1-1';
它的過程實際上是先通過非聚集索引index_birthday查詢到user_birthday = '1997-1-1』的所有記錄的主鍵id值,然後通過得到的主鍵id值執行聚集索引查詢,找到主鍵id值所在行的真實位置,最後,從得到的真實資料中得到user_name欄位的值返回,得到最終結果

但是我們執行一下兩條語句是不需要進行二次查詢的,直接就可以從非聚集索引的節點裡獲取到值了

select user_id,user_birthday from user_inf where user_birthday = '1997-1-1';

select user_birthday from user_inf where user_birthday = '1997-1-1';

也就是說,如果不查詢非索引的字段的話是不需要二次查詢的

解決方法:

採用覆蓋索引

建立兩列以上的索引,即可查詢符合索引裡的列的資料而不需要進行回表二次查詢,如index_username_birthday;執行:

create index index_username_birthday on user_inf(user_name,user_birthday);
則上面原本進行二次查詢的語句的執行過程會變為通過非聚集索引index_username_bi-rthday查詢user_birthday的葉節點的內容,但是,葉節點中除了有表的主鍵id的值以外還有user_name欄位的值,而我們只查詢id和user_name兩個欄位的值,因此,不需要通過主鍵id再次回表查詢了,直接取得值返回就可以了;通過這種覆蓋索引直接查詢的方式可以避免二次查詢的問題,大大提高查詢的效能

主鍵:表通常具有包含唯一標識表中每一行的值的一列或一組列。這樣的一列或多列被稱為表的主鍵(pk),用於強制表的的實體完整性。 乙個表只能有乙個primary key約束,並且該列不能為空值。 建立主鍵時,資料庫引擎會主動建立唯一的索引的來強制實施primary key約束的唯一性要求。如果表中不存在聚集索引或未顯示指定聚集索引,則將建立唯一的聚集索引以強制實施primary key約束。

建立索引的原則:

定義為主鍵的資料列一定要建立索引

定義為外來鍵列的一定要建立索引

對於經常查詢的列最好建立索引

對於需要在指定範圍內的快速或頻繁查詢的資料列

經常出現order by、group by、distinct後面的字段,建立索引。如果建立的是復合索引,則索引中的字段順序要和這些關鍵字後面的字段順序一致,否則索引不會被使用

經常出現在where子句中的資料列

對於查詢很少涉及到的列,重複值比較多的列不要建立索引,因為既然這些列很少用到,則新增索引不能增加效率,反而會降低系統的維護速度和增大空間需求

對於定義為text、image、bit的資料型別的列不要建立索引 因為這些列要麼資料量很大,要麼使用很少,不利於索引

限制表的索引數目。對於乙個存在大量更新操作的表,所建立的索引的數目一般不超過三個,最多不要超過15個。

索引的缺點:

索引雖說會太高查詢速度,但是會使寫入的效率降低,因為索引採用平衡樹的結構來排序,並且這個結構必須要一直保持在正確的狀態下,增刪改資料都會改變平衡樹各節點中的索引資料內容,破壞樹結構,因此,在每次資料改變時,dbms必須去重新梳理(索引)的結構以確保它的正確性,這會額外帶來很打的效能開銷,所以不是所有的表都能建立索引,只有資料量大的表才適合建立索引,並且建立的適合的列上效能會更好

聚集與非聚集索引

聚集與非聚集索引 索引是在資料庫表或者檢視上建立的物件,目的是為了加快對錶或檢視的查詢的速度 按照儲存方式分為 聚集與非聚集索引 按照維護與管理索引角度分為 唯一索引 復合索引和系統自動建立的索引 索引的結構是由 根節點 非葉節點 非葉節點 葉節點 1 聚集索引 表中儲存的資料按照索引的順序儲存,檢...

聚集索引與非聚集索引

非聚集索引也是堆結構?其實sqlserver有幾種頁面型別 資料都使用一頁一頁來儲存,就像windows的記憶體也是使用頁面來組織的 感興趣的朋友可以了解下,希望本文可以增加你們對非聚集索引結構的理解。我們知道sqlserver的資料行的儲存有兩種資料結構 a 堆b b樹 binary 二叉樹 資料...

聚集索引與非聚集索引

一 聚集索引概念 漢語字典的正文本身就是乙個聚集索引。比如,我們要查 安 字,就會很自然地翻開字典的前幾頁,因為 安 的拼音是 an 而按照拼音排序漢字的字典是以英文本母 a 開頭並以 z 結尾的,那麼 安 字就自然地排在字典的前部。如果您翻完了所有以 a 開頭的部分仍然找不到這個字,那麼就說明您的...