這裡是修真院小課堂,本篇分析的主題是
《普通索引和唯一索引的思考》
索引是對資料庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問資料庫表中的特定資訊。 從資料搜尋實現的角度來看,索引也是另外一類檔案/記錄,它包含著可以指示出相關資料記錄的各種記錄。
在了解資料庫索引之前,首先了解一下資料庫索引的資料結構基礎:b+tree
說一下重點,淺藍色的塊我們稱之為乙個磁碟塊,可以看到每個磁碟塊包含幾個資料項(深藍色所示)和指標(黃色所示)。如磁碟塊1包含資料項17和35,包含指標p1、p2、p3,p1表示小於17的磁碟塊,p2表示在17和35之間的磁碟塊,p3表示大於35的磁碟塊。真實的資料存在於葉子節點即3、5、9、10、13、15、28、29、36、60、75、79、90、99。非葉子節點只不儲存真實的資料,只儲存指引搜尋方向的資料項,如17、35並不真實存在於資料表中。
查詢時b+tree到底是怎麼運作的?簡單分析一下:
如果要查詢資料項29,那麼首先會把磁碟塊1由磁碟載入到記憶體,此時發生一次io,在記憶體中用二分查詢確定29在17和35之間,鎖定磁碟塊1的p2指標,記憶體時間因為非常短(相比磁碟的io)可以忽略不計,通過磁碟塊1的p2指標的磁碟位址把磁碟塊3由磁碟載入到記憶體,發生第二次io,29在26和30之間,鎖定磁碟塊3的p2指標,通過指標載入磁碟塊8到記憶體,發生第三次io,同時記憶體中做二分查詢找到29,結束查詢,總計三次io。真實的情況是,3層的b+tree可以表示上百萬的資料,如果上百萬的資料查詢只需要三次io,效能提高將是巨大的,如果沒有索引,每個資料項都要發生一次io,那麼總共需要百萬次的io,顯然成本非常非常高。
b+tree的性質:
1.n棵子tree的結點包含n個關鍵字,不用來儲存資料而是儲存資料的索引。
2.所有的葉子結點中包含了全部關鍵字的資訊,及指向含這些關鍵字記錄的指標,且葉子結點本身依關鍵字的大小自小而大順序鏈結。
3.所有的非終端結點可以看成是索引部分,結點中僅含其子樹中的最大(或最小)關鍵字。
索引分類:
mysql的索引分為單列索引(主鍵索引,唯一索引,普通索引)和組合索引。
單列索引:乙個索引只包含乙個列,乙個表可以有多個單列索引。
組合索引:乙個組合索引包含兩個或兩個以上的列。
普通索引,這個是最基本的索引。
唯一索引,與普通索引類似,但是不同的是唯一索引要求所有的類的值是唯一的,這一點和主鍵索引一樣,允許有空值。 建立唯一索引乙個比較重要的作用是避免資料出現重複。
主鍵索引,不允許有空值。主鍵索引建立的規則是 int優於varchar,一般在建表的時候建立, 最好是與表的其他欄位不相關的列或者是業務不相關的列。一般會設為 int 而且是 auto_increment自增型別的。
索引的優點:
1.可以通過建立唯一索引或者主鍵索引,保證資料庫表中每一行資料的唯一性
2.建立索引可以大大提高檢索的資料,以及減少表的檢索行數
3.在表連線的連線條件,可以加速表與表直接的相連
4.在分組和排序字句進行資料檢索,可以減少查詢時間中 分組 和 排序時所消耗的時間(資料庫的記錄會重新排序)
5.建立索引,在查詢中使用索引,可以提高效能。
索引的缺點:
1.在建立索引和維護索引,會耗費時間,隨著資料量的增加而增加
2.索引檔案會占用物理空間,除了資料表需要占用物理空間之外,每乙個索引還會占用一定的物理空間
3.當對表的資料進行 insert,update,delete 的時候,索引也要動態的維護,這樣就會降低資料的維護速度,(建立索引會占用磁碟空間的索引檔案)。
關於索引的優缺點大家結合b+tree很容易就理解了。
1:如何建立索引?
2:隱式型別轉換對mysql選擇索引的影響?
3:什麼情況下建索引?
4.什麼情況不建索引?
5:索引對提高查詢速度能提公升多少效能?
sql插入索引語句:
普通索引:alter table `table_name` add index index_name ( `column` )
唯一索引:alter table `table_name` add unique ( `column` )
主鍵索引:alter table `table_name` add primary key ( `column` )
當文字欄位與數字進行比較時,由於型別不同,mysql 需要做隱式型別轉換才能進行比較。
預設轉換規則是:
不同型別全都轉換為浮點型
如果欄位是字元,條件是整型,那麼會把表中字段全都轉換為整型
什麼情況下要建立索引:
1.在經常需要搜尋的列上,可以加快索引的速度。
2.主鍵列上可以確保列的唯一性。
3.在表與表的而連線條件上加上索引,可以加快連線查詢的速度。
4.在經常需要排序(order by),分組(group by)和的distinct 列上加索引 可以加快排序查詢的時間, (單獨order by 用不了索引,索引考慮加where 或加limit)。
5.盡量選擇區分度高的列作為索引。
6.索引列不能參與計算,保持列「乾淨」。
7.盡量的擴充套件索引,不要新建索引
什麼情況下不建立索引:
1.查詢中很少使用到的列 不應該建立索引,如果建立了索引然而還會降低mysql的效能和增大了空間需求。
2.很少資料的列也不應該建立索引,比如 乙個性別字段 0或者1,在查詢中,結果集的資料佔了表中資料行 的比例比較大,mysql需要掃瞄的行數很多,增加索引,並不能提高效率。
3.定義為text和image和bit資料型別的列不應該增加索引。
4.當表的修改(update,insert,delete)操作遠遠大於檢索(select)操作時不應該建立索引,這兩個操作是互斥的關係。
如果對學員qq號做了乙個唯一索引,在插入資料的時候,是否需要先判斷這個qq號已經存在了?
如果qq號做了唯一索引,我們插入時會提示我們重複插入,阻止我們插入。但是要是在現實業務中,我們需要把這個反饋給客戶端,所以我們是需要做乙個判斷,如果qq號重複就把這個資訊反饋給客戶端。
參考二:型別轉換對mysql選擇索引的影響
參考三:mysql8.0參考手冊
MySQL 普通索引 唯一索引和主索引
1 普通索引 普通索引 由關鍵字key或index定義的索引 的唯一任務是加快對資料的訪問速度。因此,應該只為那些最經常出現在查詢條件 wherecolumn 或排序條件 orderbycolumn 中的資料列建立索引。只要有可能,就應該選擇乙個資料最整齊 最緊湊的資料列 如乙個整數型別的資料列 來...
MySQL 普通索引 唯一索引和主索引
1.普通索引 普通索引 由關鍵字key或index定義的索引 的唯一任務是加快對資料的訪問速度。因此,應該只為那些最經常出現在查詢條件 where column 或排序條件 order by column 中的資料列建立索引。只要有可能,就應該選擇乙個資料最整齊 最緊湊的資料列 如乙個整數型別的資料...
MySQL 普通索引 唯一索引和主索引
1 普通索引 普通索引 由關鍵字key或index定義的索引 的唯一任務是加快對資料的訪問速度。因此,應該只為那些最經常出現在查詢條件 wherecolumn 或排序條件 orderbycolumn 中的資料列建立索引。只要有可能,就應該選擇乙個資料最整齊 最緊湊的資料列 如乙個整數型別的資料列 來...