先看一下隔離級別, 隔離級別首先要明確 ,隔離的越重,那么自然會失去效率,為什么有這么多的隔離級別,其實就是平衡業務關系盡可能的提高效率。
下面看下隔離級別和介紹:
讀未提交是指:一個事務還沒提交時,它做的變更就能被別的事務看到。
讀提交是指:一個事務提交之后,它做的變更才會被其他事務看到。
可重復讀是指:一個事務執行過程中看到的數據,總是跟這個事務在啟動時看到的數據是一致的。當然在可重復讀隔離級別下,未提交變更對其他事務也是不可見的。
串行化:顧名思義是對于同一行記錄,“寫”會加“寫鎖”,“讀”會加“讀鎖”。當出現讀寫鎖沖突的時候,后訪問的事務必須等前一個事務執行完成,才能繼續執行。其中“讀提交”和“可重復讀”比較難理解,所以我用一個例子說明這幾種隔離級別。假設數據表 T 中只有一列,其中一行的值為 1,下面是按照時間順序執行兩個事務的行為
假如 mysql 修改(update) age?這個這個字段 ,由age 36 修改為 18
首先1.啟動事物?2,修改值 ?3?commit(提交事物 )整個過程結束。
那么當另外一個事物正好訪問age 這個修改的字段是 改怎么處理呢。
讀提交 :必須等修改的事物 commit 提交之后才能訪問,也就是 在沒有修改事物提交之前還是訪問的36?
讀未提交: 表示 我可以等你不提交,就能讀到數據,那么這個時候讀到的數據就是18 (雖然修改事物沒有提交)
可重復讀,表示 我這個讀事物前后一致,也就是說我讀事物在沒有提交之前 讀到什么數據 就一直是什么數據,(讀事物沒有commit之前)
串行化: 當一個事物會加鎖,執行完之后 另外一個事物才能執行。當 查詢事物commit 之后 修改事物才能執行,或者當修改事物commit 之后 查詢事物才能執行。
再說一下索引:
mysql 數據庫大部分用的是innoDB,見索引要注意回表問題。
先說一下回表, innoDB采用B+樹的方式,它分為主鍵索引(聚簇索引),業務類索引(非聚簇索引),當我們查詢一個字段的時候,mysql 會返回主鍵 然后 再把數據返回,
比如 * where age =18 他會先用age 這個業務索引找到 主鍵id ?然后用主鍵id 取找出所有查詢的數據 這個過程叫回表。
你的 索引設計 如果設計不當很可能會增加 回表的次數 從而影響 查詢效率
舉例說一下:比如查詢?where age =18 and sex =‘男’ ?你的索引 age 但是sex 沒有,
這樣的話 按照最左匹配原則,age 是會走索引的,但是sex 沒有索引 ?,這樣就是增加一次回表,即先通過age 查詢id 然后 用id 找出數據 看看sex是否符合。
但是如果你 (age, sex) 這樣做聯合索引 按照 最左匹配原則 你age 首先說可以使用,那么 你在使用查詢語句的where age =18 and sex =‘男’ ? 時候,減少了一次回表 ?(這叫索引下推)
拿怎么設計呢,比如你的業務需求中 關于年齡和性別這兩個是高頻查詢次數,那么就直接設計聯合索引,這樣還能減少單獨設計age 這個索引(索引最左原則)
?