1) mysql為甚用b+樹索引(innodb)
不用普通的二叉樹,因為對于大的資料量,二叉樹的高度太高,索引的效率低下。這裡主要說明為什麼不用B樹(B-樹就是B樹),而是用B+樹。
二叉樹查詢的時間複雜度為O(logN),查詢效率已經夠高了,但為什麼還要有B樹和B+樹呢?答案是磁盤IO。
平衡二叉樹由于樹的高度太大造成磁盤IO讀寫過于頻繁,進而導緻效率低下,是以多路查找樹-B樹/B+樹應運而生。
2) 聯合索引:
mysql可以将多個列按照順序作為一個索引,這種索引叫做聯合索引。
3) 索引的最左字首原則
索引的最左比對原則是:假如索引列分别為A,B,C,順序也是A,B,C,那麼:
· 查詢的時候,如果查詢【A】,【A,B】,【A,B,C】,可以使用索引查詢。
· 如果查詢的時候,查詢【A,C】,由于中間缺失了B,那麼C這個索引是用不到的,隻能用到A索引。
· 如果查詢的時候,查詢【B】,【B,C】或【C】,由于缺失了最左字首A,那麼是用不到這個聯合索引的,除非有其他索引。
· 如果查詢的時候使用範圍查詢,并且是最左字首,那麼可以用到索引,但是範圍後面的字段無法用到索引。
4) 建索引的其他原則
1、盡量選擇區分度高的列作為索引,區分度公式:count(distinct col)/count(*),表示字段不重複的比例,比例越大,我們掃描的記錄數就越少,唯一性的列的區分度為1。這就是為什麼不建議在狀态,性别這樣區分度很小的列上建立索引的原因。
2、索引列在sql語句中不能參與運算,否則會導緻索引失效。例如from_unixtime(create_time) = ’2021-07-29’就不能使用到索引,原因很簡單,b+樹中存的都是資料表中的字段值,但進行檢索時,需要把所有元素都應用函數才能比較,顯然成本太大。應該改成create_time = unix_timestamp(’2021-07-29’);
3、聯合索引比單個索引的成本效益更高。例如,建立【A,B,C】這個聯合索引,相當于建立了【A】,【A,B】,【A,B,C】這三個索引。這就要求我們盡量的擴充索引而不是建立索引,具體情況還需具體分析。
4、頻繁進行查詢的字段應該建立索引,與其他表進行關聯的字段可以考慮建立索引,查詢中排序的字段可以考慮建立索引以提高排序的效率(這裡舉個例子,很多時候查詢記錄希望按照建立時間倒序傳回,通常有人會這樣做order by create_time desc,但是如果create_time不是索引,而這個表有自增主鍵id,那麼order by id desc傳回結果一樣,但是效率會提高)。
5) 是否走索引
show keys from table. -- 執行檢視所有索引