數據庫索引相關問題點算法
1.爲何要給表加上主鍵?數據庫
沒有建立主鍵的表,他的數據是無序的放在磁盤中,一行行的排列很整齊,查詢時也要一行行的掃描。 建立了主鍵的表,在磁盤中的存儲結構,由整齊的結構變成樹狀結構,也就是平衡樹(B-Tree,B+Tree)結構。整個變成一個索引,也就是所謂的「彙集索引」。 固然,也有使用哈希結構的索引,主流的關係型數據庫仍是默認平衡樹做爲索引數據結構的。 不一樣的數據庫存儲引擎,建立的索引結構也不一樣。
2.爲何一個表只能有一個主鍵?服務器
一個表只能有一個「彙集索引」,由於主鍵的做用是把表的數據格式轉化爲樹形結構放置,因此一個表只有一個主鍵。 聯合主鍵是主鍵的一種,是由多個字段組成的主鍵,主鍵並不必定只有一個字段,這裏要搞清楚。
3.爲何加索引後會使查詢變快?數據結構
select * from table where id=82; 假如一張他table表有一億條數據 ,須要查找id爲82的數據,沒建立索引的狀況,多是一條一條的去匹配,最差的打算是須要匹配一億次,一億次匹配查詢,就是一億次IO開銷,按照服務器的I/O能力與CPU的運算能力,須要幾個月才能得出結果。 往table表中添加id爲主鍵,表的數據結構變化爲平衡樹結構。
樹形結構:由根節(root)、分支(branches)、葉(leaves)三級節點組成,其中分支節點能夠有多層。 下圖展現定位id爲82的過程:
算法步驟:性能
1.讀取root節點,判斷82大於在0-120之間,走左邊分支; 2.讀取左邊branch節點,判斷82大於80且小於等於120,走右邊分支; 3.讀取右邊leaf節點,在該節點中找到數據82及對應的id; 4.使用rowid去物理表中讀取記錄數據塊。
在整個索引中,只進行了三次I/O操做,就定位到了id。spa
對於一億的數據量最多要查詢多少次呢?code
樹形結構,數據每增長一層,數據量就是成指數級的增加。blog
若是有2個分支,一億條數據,最多查詢27次就能夠定位到數據,若是樹結構是4個分叉,最多15次就能查到.索引
4.爲何加索引後會使寫入、修改、刪除變慢?ip
緣由很簡單,刪改數據都會改變平衡樹各節點中的索引數據內容,破壞樹結構,每次數據改變時,數據庫管理系統都要從新梳理樹結構,還會帶來不小的性能開銷。索引會給查詢之外的操做帶來反作用。
5.非彙集索引是怎樣的呢?
非彙集索引,就是咱們平時使用的向某個字段添加索引,非彙集索引和彙集索引同樣,一樣能夠採用平衡樹做爲索引數據結構,索引樹各節點中的值,來自於表中字段的值,若是給字段建立一個索引,字段的值就會被複製出來,用於建立索引。給表添加索引,就會增長表的體積,佔用更多的磁盤存儲空間。非彙集索引都是獨立存在的,每一個索引之間不存在關聯。
6.彙集索引和非彙集索引的區別?
經過彙集索引能夠查到須要查找到的是每行的數據,經過非彙集索引查到的是記錄對應的主鍵,再經過主鍵查找相應的值。無論任何查表的方式,都會經過主鍵定位到數據,彙集索引(主鍵)是通往數據的惟一途徑。
7.什麼狀況下要同時在兩個字段上建索引?
可能還有一種特殊狀況,能夠不經過彙集索引就獲得須要的數據,這種非主流的方法 稱之爲「覆蓋索引」查詢。也就是平時建立的複合索引或者多字段索引查詢。爲一個索引指定兩個字段,那麼兩個字段的內容就同步到索引中。若是經過其中的一個字段查另外一個字段時,正好在索引中有存儲,就不用經過彙集索引啦。
//建立用戶的index_name_and_age 索引
create index index_name_and_age on user_info(name, age);
//經過用戶名查找年齡
select age from user where name = '科比';
這種狀況,能夠建立複合索引了。