MySql數據庫知識點總結02-索引

     數據庫索引是數據庫管理系統中一個排序的數據結構,以協助快速查詢、更新數據庫表中數據。索引的實現通常使用B樹及其變種B+樹。
     索引的目的在於提高查詢效率,與我們查閱圖書所用的目錄是一個道理:先定位到章,然後定位到該章下的一個小節,然後找到頁數。相似的例子還有:查字典,查火車車次,飛機航班等。
     考慮到磁盤IO是非常高昂的操作,計算機操作系統做了一些優化,當一次IO時,不光把當前磁盤地址的數據,而是把相鄰的數據也都讀取到內存緩衝區內,因爲局部預讀性原理告訴我們,當計算機訪問一個地址的數據的時候,與其相鄰的數據也會很快被訪問到。每一次IO讀取的數據我們稱之爲一頁(page)。具體一頁有多大數據跟操作系統有關,一般爲4k或8k,也就是我們讀取一頁內的數據時候,實際上才發生了一次IO,這個理論對於索引的數據結構設計非常有幫助。
     Hash類型的索引:查詢單條快,範圍查詢慢。
     B樹類型的索引:b+樹,層數越多,數據量指數級增長(我們就用它,因爲innodb默認支持它)。
  不同的存儲引擎支持的索引類型也不一樣
     InnoDB 支持事務,支持行級別鎖定,支持 B-tree、Full-text 等索引,不支持 Hash 索引。
     MyISAM 不支持事務,支持表級別鎖定,支持 B-tree、Full-text 等索引,不支持 Hash 索引。
     Memory 不支持事務,支持表級別鎖定,支持 B-tree、Hash 等索引,不支持 Full-text 索引。
     1.由於索引僅包含hash code和記錄指針,所以,MySQL不能通過使用索引避免讀取記錄。但是訪問內存中的記錄是非常迅速的,不會對性造成太大的影響。
     2.不能使用hash索引排序。
     3.Hash索引不支持鍵的部分匹配,因爲是通過整個索引值來計算hash值的。
     4.Hash索引只支持等值比較,例如使用=,IN( )和<=>。對於WHERE price>100並不能加速查詢。
     爲了儘量減少I/O操作,磁盤讀取每次都會預讀,大小通常爲頁的整數倍。即使只需要讀取一個字節,磁盤也會讀取一頁的數據(通常爲4K)放入內存,內存與磁盤以頁爲單位交換數據。因爲局部性原理認爲,通常一個數據被用到,其附近的數據也會立馬被用到。
     B樹:如果一次檢索需要訪問4個節點,數據庫系統設計者利用磁盤預讀原理,把節點的大小設計爲一個頁,那讀取一個節點只需要一次I/O操作,完成這次檢索操作,最多需要3次I/O(根節點常駐內存)。數據記錄越小,每個節點存放的數據就越多,樹的高度也就越小,I/O操作就少了,檢索效率也就上去了。
     B+樹:非葉子節點只存key,大大滴減少了非葉子節點的大小,那麼每個節點就可以存放更多的記錄,樹更矮了,I/O操作更少了。所以B+Tree擁有更好的性能。
     由於B+樹在內部節點上不包含數據信息,因此在內存頁中能夠存放更多的key。 數據存放的更加緊密,具有更好的空間局部性。因此訪問葉子節點上關聯的數據也具有更好的緩存命中率。
     B+樹的葉子結點都是相鏈的,因此對整棵樹的便利只需要一次線性遍歷葉子結點即可。而且由於數據順序排列並且相連,所以便於區間查找和搜索。而B樹則需要進行每一層的遞歸遍歷。相鄰的元素可能在內存中不相鄰,所以緩存命中性沒有B+樹好。
   優點:
     1.通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性。
     2.可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。
     3.可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。
     4.在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。
     5.通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。
   缺點:
     1.創建索引和維護索引要耗費時間,這種時間隨着數據量的增加而增加。
     2.索引需要佔物理空間,除了數據表佔數據空間之外,每一個索引還要佔一定的物理空間,如果要建立聚簇索引,那麼需要的空間就會更大。

     3.當對錶中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。

索引是建立在數據庫表中的某些列的上面。在創建索引的時候,應該考慮在哪些列上可以創建索引,在哪些列上不能創建索引。
     1.在經常需要搜索的列上,可以加快搜索的速度;
     2.在作爲主鍵的列上,強制該列的唯一性和組織表中數據的排列結構;
     3.在經常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;
     4.在經常需要根據範圍進行搜索的列上創建索引,因爲索引已經排序,其指定的範圍是連續的;
     5.在經常需要排序的列上創建索引,因爲索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;
     6.在經常使用在WHERE子句中的列上面創建索引,加快條件的判斷速度。
     1.對於那些在查詢中很少使用或者參考的列不應該創建索引。這是因爲,既然這些列很少使用到,因此有索引或者無索引,並不能提高查詢速度。相反,由於增加了索引,反而降低了系統的維護速度和增大了空間需求。
     2.對於那些只有很少數據值的列也不應該增加索引。這是因爲,由於這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行佔了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,並不能明顯加快檢索速度。
     3.對於那些定義爲text, image和bit數據類型的列不應該增加索引。這是因爲,這些列的數據量要麼相當大,要麼取值很少。
     4.當修改性能遠遠大於檢索性能時,不應該創建索引。這是因爲,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大於檢索性能時,不應該創建索引。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章