這篇文章的知識點來自於極客時間專欄<<MySQL實戰45講>>,本文持續更新。
索引
索引的目的:提高查詢效率。
常見索引模型:哈希表、有序數組、搜索樹
哈希表:鍵 - 值(key - value)對。
哈希思路:把值放在數組裏,用一個哈希函數把key換算成一個確定的位置,然後把value放在數組的這個位置
哈希衝突(多個 key 值經過哈希函數的換算,會出現同一個值的情況)的處理辦法:鏈表
哈希表適用場景:只有等值查詢的場景,比如 Memcached 及其他一些 NoSQL 引擎。
有序數組:按順序存儲。查詢用二分法就可以快速查詢,時間複雜度是:O(log(N))
有序數組查詢效率高,更新效率低,往中間插入一個記錄就必須得挪動後面所有的記錄,成本太高。
有序數組的適用場景:靜態存儲引擎。
二叉搜索樹:每個節點的左兒子小於父節點,父節點又小於右兒子
二叉搜索樹:查詢時間複雜度O(log(N)),更新時間複雜度O(log(N))
數據庫存儲大多不適用二叉樹,因爲樹高過高,會適用N叉樹
MySQL表引擎InnoDB中的索引模型:B+Tree
索引類型:主鍵索引、非主鍵索引
主鍵索引的葉子節點存的是整行的數據(聚簇索引),非主鍵索引的葉子節點內容是主鍵的值(二級索引)
主鍵索引和普通索引的區別:主鍵索引只要搜索ID這個B+Tree即可拿到數據。普通索引先搜索索引拿到主鍵值,再到主鍵索引樹搜索一次(回表),所以在應用中儘量使用主鍵查詢。
一個數據頁滿了,按照B+Tree算法,新增加一個數據頁,叫做頁分裂,會導致性能下降。空間利用率降低大概50%。當相鄰的兩個數據頁利用率很低的時候會做數據頁合併,合併的過程是分裂過程的逆過程。
自增主鍵
使用自增主鍵的好處:
- 自增主鍵一般用整型做主鍵,則二級索引葉子節點只要 4 個字節;而如果使用業務字段做主鍵,比如字符串類型的身份證號,每個二級索引的葉子節點得佔用約 20 個字節。
- 插入數據時,自增主鍵能保證有序插入,避免了頁分裂。
從性能和存儲空間方面考量,自增主鍵往往是更合理的選擇。
使用業務字段做主鍵的使用場景:
- 只有一個索引
- 該索引必須是唯一索引
這就是典型的 KV 場景。由於沒有其他索引,所以不用考慮其他索引的葉子節點大小的問題.
重建索引
重建索引的目的:節省空間
重建索引的辦法:alter table T engine=InnoDB
聯合索引
覆蓋索引:如果查詢條件使用的是普通索引(或是聯合索引的最左原則字段),查詢結果是聯合索引的字段或是主鍵,不用回表操作,直接返回結果,減少IO磁盤讀寫讀取正行數據
最左前綴:聯合索引的最左 N 個字段,也可以是字符串索引的最左 M 個字符
聯合索引:根據創建聯合索引的順序,以最左原則進行where檢索,比如(age,name)以age=1 或 age= 1 and name=‘張三’可以使用索引,單以name=‘張三’ 不會使用索引,考慮到存儲空間的問題,還請根據業務需求,將查找頻繁的數據進行靠左創建索引。
索引下推:like 'hello%’and age >10 檢索,MySQL5.6版本之前,會對匹配的數據進行回表查詢。5.6版本後,會先過濾掉age<10的數據,再進行回表查詢,減少回表率,提升檢索速度。