- 聚簇索引:聚簇=索引和數據在一起,又名主鍵索引,是主鍵id構建的一顆B+樹,非葉節點是主鍵id,葉子節點是真實數據。其他索引統稱二級索引,也稱為非聚簇索引。
- 覆蓋索引:查找的數據就在索引樹上,不需要回表。
user表(id, name, age, phone),100行初始數據,有主鍵索引,name和age構建的聯合索引
select id, name, age from user where id=?; √ 查找的id, name, age都在主鍵索引上
select name, age from user where name=? and age=?; √ 查找的name, age都在主鍵索引上
select * from user where name=? and age=?; x,需要的phone不在聯合索引,需要回表
- 回表:從二級索引查詢回到主鍵索引中
select * from user where name=? and age=?;
1- 獲取name和age的索引樹
2- 從二級索引葉子節點找到具體的id
3- 獲取主鍵索引(回表,即拿到初始所有數據)
4- 從主鍵索引葉子節點找到具體的數據返回
- 全表掃描:一行行記錄查詢,全部回表,少一行都不行
select * from user where id between 1 and 99; x, 沒有掃描第100行
- 索引下推ICP:將服務層非索引的篩選下推到存儲引擎層,主要適用于聯合索引
select * from user where name=? and age=?
1- 服務端向db發起請求,db連接層建立連接
2- db服務層經過緩存查,解析器解析,優化器優化后生成執行計劃
3- 引擎層查磁盤獲取到name和age索引樹,通過name篩選出一批數據,獲取id
4- 從磁盤獲取主鍵索引,通過id進行篩選。
5- sql5.6之前將篩選后的數據返回給服務層,服務層通過phone篩選后返回服務端,5.6之后引擎層直接處理,將處理好的數據返回給服務層,減少了無效數據的傳輸
6- 如果是聯合索引,比如abc聯合索引,a=xx and b like %lucas。以前沒有icp,會先篩選出a然后服務層篩選b,有了icp后,會在聯合索引的b+樹種篩選a,引擎層直接篩選b,不需要回表
-
事務的ACID特性
A-原子性:事務內的多個sql同時成功,同時失敗,靠undo日志保證
C-一致性:事務執行前后,數據從一個合法狀態轉為另一個合法狀態,靠業務保證
I-隔離性:事務之間相互隔離,靠MVCC和鎖保證
D-持久性:持久化到磁盤,靠redo日志保證 -
數據并發問題
臟寫:修改其他事物未提交的數據(a將1修改為2,b將2修改為3,a提交,預期是2,但是結果是3,a寫的是錯的)
臟讀:讀取其他事務未提交的數據(a將1修改為2,b讀發現結果是2,但是a回滾了,b讀的是錯的)
不可重復讀:讀取到的數據有變化(a讀取發現是1,b將1修改為2,a在同個事務內再次讀取,發現是2了)
幻讀:行數有變化(a讀取發現2行,b新增了1行,a在同個事務內再次讀取,發現是3行了) -
事務隔離級別
讀未提交:可以讀取其他事務未提交的結果,僅解決臟寫(寫時加了s鎖)
讀已提交:只能讀取其他事務提交的結果,解決臟寫和臟讀
可重復讀(InnoDB默認):同個事務內,讀取結果不變,解決臟寫,臟讀和不可重復讀(mvcc讀快照)
串行化(不推薦):串行執行,解決所有并發問題 -
鎖
讀讀:一般共享鎖(可讀不可寫),select for update可以給讀讀加排他鎖
讀寫或寫寫:只要有寫在,一定加排他鎖(不能讀也不能寫) -
點查:根據索引查詢某行數據,一般通過唯一索引查詢