1、隔離級別
innoDB透過間隙鎖鎖定查詢範圍避免被其他事物修改
未提交讀(導致髒讀)、已提交讀(導致不可重複讀)、可重複讀(mysql預設,導致幻讀)、序列化
髒讀:事物執行的過程讀到其他事物未提交的資料
不可重複讀:事物a在多次讀取某資料時,事物b進行了修改,導致食物a兩次讀取結果不一樣
幻讀:前後兩次查詢得到的結果不一樣,事物前後兩次查詢統一範圍資料時事物b進行了插入修改並提交
2、SQL最佳化
a.增加索引;但是要避免索引失效如like、函式等
b.避免返回不必要的資料列
c.適當最佳化sql結構,如避免子查詢、全表掃描等
d.分庫分表,單表資料量比較大時
e.讀寫分離,讀多寫少時
3、索引失效情況
索引:主鍵索引、普通索引
使用ecplain 查詢sql當前執行計劃
a 索引列上做函式運算導致失效
b 組合索引需要按照最左匹配法則
c 索引列存在隱式轉換時候,即索引列是字串型別但是沒有加引號
d 索引列使用不等號或者not查詢導致失效
e 使用like並且%加在前面時候失效,由於不符合最左匹配所以失效
f 使用or但是語句前後沒有同時使用索引的時候也會失效
4、update執行時如果where包含索引列且只執行一個語句,使用行鎖,否則使用表鎖
5、為什麼索引不適用二叉樹而使用B+樹
二叉樹每次插入大的值需要新增到右側,深度較高,查一次就要進行一次IO,查詢效率沒有幫助。
紅黑樹也是最大的插到右側,但是會進行自旋,不會全都加到一條線,相當於平衡二叉樹,查詢次數差不多能減少一半,但是深度還是比較高,而且自旋轉也需要消耗資源。
B樹一個節點可以儲存多個元素,深度較低。
B+樹是對B樹的一個增強,如圖
innoDB引擎:自增的在新增的時候不需要修改節點,節省時間
一般推薦建立一到兩個的聯合索引(複合索引)
Explain 命令中的 type 列,顯示MySQL查詢所使用的 關聯型別(Join Types) 或者 訪問型別,它表明 MySQL決定如何查詢表中符合條件的行。
常見訪問型別效能由最差到最優依次為:
ALL < index < range < ref < eq_ref < const < system。
一般需要range級別或者達到ref級別
range級別:
- 範圍條件查詢:在
WHERE
子句裡帶有BETWEEN
、>
、<
、>=
、<=
的查詢。 - 多個等值條件查詢:使用
IN()
和OR
,以及使用like
進行字首匹配模糊查詢
非主鍵索引的都可以稱之為二級索引,二級索引是非聚集索引,沒有在葉子結點包含全部的資料,只存主鍵的id,需要根據主鍵id進行回表再查詢;
mysql5.6以後的索引下推可以減少回表
覆蓋索引查詢的欄位都在索引列中,不需要進行回表所以效率高一些。
mysql表關聯的底層實現原理:當資料量比較大的時候就算走索引也比較慢
explain關鍵引數type:
索引最佳化:
- 全值匹配:使用複合索引時候,查詢條件包括索引所有的列;
- 索引列上少算數;使用函式沒有辦法根據有序性進行檢索;
- 範圍索引後面會失效;前面使用有序範圍後,後面的欄位是無序的;如果第一個欄位搜尋範圍小想強制使用索引可以加上關鍵字Force Index(索引名稱)防止後面欄位全表掃描
- 儘量使用覆蓋索引,不寫星號(防止回表);explice檢視extra顯示index
- 不等空值還有or,索引失效要少用,還有not in 、not exists也會失效,範圍查詢mysql自己判斷
- like百分號寫右邊;
- 單引號不要省略
sql最佳化
- 不要寫*
- 用小表驅動大表
- 連線查詢代替子查詢;具體場景具體分析
- 提升group by效率,分組欄位新增索引
- 批次插入最佳化,mybatis提供了sqlsession.getMapper(EmpMapper.class).insertBatch(資料list),五百以內
- 使用limit
- union all替代union 第一個不會去重,去重時需要遍歷排序等內部操作
- 儘量少關聯