1.sql優化
1.1select字句中不要使用* 理由:把*替換成表中的字段名,需要解析一次數據字典,有性能損耗
1.2from字句後的主表最好是記錄數最少的表(oracle rbo模式,從from最右邊的表開始掃描)
1.3範圍大的條件放在where末尾,where字句的解析順序是從後到前
1.4子查詢in迭代的是子表,exists迭代的是外表,外大用in,內大用exists
1.5無論何時not exists由於not in
1.6mysql中 join 子查詢 性能高於 where 子查詢
1.7存在null值的列隨數據分佈情況,可能不走索引,count不字句不計算含有null值的記錄
1.8like字句左%不會使用索引
1.9order by後儘量使用索引列排序,多個排序字段含有不同的索引時也會導致索引失效
1.10索引列不能是表達式的一部分
不使用索引:select uid from user where uid + 1 = 2;
使用索引:select uid from user where uid = 2 - 1;
1.11範圍查詢時儘可能縮小範圍
1.12子查詢不易嵌套過多層
2.mysql事務隔離級別
[RU]讀未提交:髒讀、不可重複讀、幻讀
[RC]讀已提交:會出現不可重複讀、幻讀,避免髒讀
[RR]可重複讀:會出現幻讀,避免不可重複讀,髒讀
[Serializable]串行化:髒讀,不可重複讀,幻讀都避免,性能差
髒讀:事務A讀到了事務B還沒有提交的數據
不可重複讀:事務A中多次讀取到的數據不一致
幻讀:兩個併發的事務中其中一個發生了插入、刪除操作,被另一個事務提交前讀取到
spring事務傳播行爲
1.如果有,則加入,沒有則新建(默認) REQUIRED 受父事務影響,影響父事務
2.如果有,則掛起,新建事務,沒有則新建,REQUIRED_NEW 不受父事務影響,不影響父事務
3.如果有,則加入,沒有就拋出異常
4.如果有,則加入,沒有則以沒有事務方式執行
3.mysql鎖機制
3.1mysql存儲引擎
支持事務 | 鎖粒度 | 存儲 | 外鍵 | 全文索引 | 樹索引 | |
MyISAM | N | 表鎖 | 256TB | N | Y | Y |
MEMORY | N | 表鎖 | RAM | N | N | Y |
InnoDB(默認) | Y | 行鎖、表鎖 | 64TB | Y | N | Y |
Archive | N | 頁鎖、表鎖 | NONE | N | N | N |
Archive使用場景爲只有大量的select或insert語句
3.2表鎖、頁鎖、行鎖(根據鎖粒度區分)
行鎖:通過給索引上的索引項加鎖來實現行鎖,意味着如果sql語句沒有使用到索引,是不會加行鎖的,只會加表鎖,有死鎖產生的可能
頁鎖:頁鎖是位於行鎖和表鎖之間的,性能也在兩者之間
表鎖:顧名思義,給全表加鎖,所以不會產生死鎖
死鎖:併發的兩個事物中,A事物鎖定xx主鍵索引等待xx其他索引,B事物鎖定了xx其他索引等待xx主鍵索引,則引發死鎖
3.3共享鎖、排它鎖(根據鎖的功能區分)
共享鎖:其實就是讀鎖,語法select ... lock in share mode。其他事務可以讀取,可以再加共享鎖,不可以加排他鎖。
排它鎖:排它鎖就是寫鎖,語法select ... for update。其他事務不可讀,不可加任何鎖,只能阻塞等鎖釋放,mysql innodb中默認會爲update、delete、insert操作加排他鎖。
如何儘可能避免死鎖:
1、以固定的順序訪問表和行。比如兩個更新數據的事務,事務A 更新數據的順序 爲1,2;事務B更新數據的順序爲2,1。這樣便可能會造成死鎖。
2、大事務拆小。大事務更傾向於死鎖,如果業務允許,將大事務拆小。
3、在同一個事務中,儘可能做到一次鎖定所需要的所有資源,減少死鎖概率。
4、降低隔離級別。如果業務允許,將隔離級別調低也是較好的選擇,比如將隔離級別從RR調整爲RC,可以避免掉很多因爲gap鎖造成的死鎖。
5、爲表添加合理的索引。可以看到如果不走索引將會爲表的每一行記錄添加上鎖,死鎖的概率大大增大
4.mysql索引詳解
普通索引、普通聯合索引
唯一索引、唯一聯合索引
添加索引:ALTER table table_name ADD INDEX index_name (column_list)
刪除:DROP INDEX [indexName] ON tableName;
ALTER TABLE table_name ADD UNIQUE index_name (column_list)
顯示索引信息:SHOW INDEX FROM table_name;
5.sql執行計劃
explan sql語句
type:all全表掃描、index、range、const 性能一次降低
possible_keys: 可能使用的索引
key:實際使用到的索引
rows:sql語句掃描了多少行