查找結構的進化 二分查找 二叉樹 二叉平衡樹 B-TREE :二叉平衡樹的基礎上,使載入一次節點,可以載入更多路徑數據,同時把查詢範圍縮減到更小 缺點:業務數據的大小可能遠遠超過了索引數據的大小,每次為了查找對比計算,需要把數據載入到記憶體以及 CPU 高速緩存中時,都要把索引數據和無關的業務數據全部 ...
查找結構的進化
二分查找
二叉樹
二叉平衡樹
B-TREE :二叉平衡樹的基礎上,使載入一次節點,可以載入更多路徑數據,同時把查詢範圍縮減到更小
缺點:業務數據的大小可能遠遠超過了索引數據的大小,每次為了查找對比計算,需要把數據載入到記憶體以及 CPU 高速緩存中時,都要把索引數據和無關的業務數據全部查出來。本來一次就可以把所有索引數據載入進來,現在卻要多次才能載入完。如果所對比的節點不是所查的數據,那麼這些載入進記憶體的業務數據就毫無用處,全部拋棄。
B+TREE:非葉子節點只保存索引數據,葉子節點保存索引數據與業務數據所在的地址
-
B+數據量相同的情況下,非葉子節點可以存放更多的數據,B+樹會更加矮胖,io次數會更少
-
B+樹有大量的冗餘節點(非葉子結點),會讓B+樹在插入刪除時的效率更高
-
B+樹的葉子結點用雙向鏈表連了起來,有益於範圍查詢,而B樹只能遍歷。
聚簇索引和非聚簇索引
如果葉子節點存儲的是實際數據的就是聚簇索引,一個表只能有一個聚簇索引;如果葉子節點存儲的不是實際數據,而是主鍵值則就是二級索引,一個表中可以有多個二級索引。
在使用二級索引進行查找數據時,如果查詢的數據能在二級索引找到,那麼就是「索引覆蓋」操作,如果查詢的數據不在二級索引里,就需要先在二級索引找到主鍵值,需要去聚簇索引中獲得數據行,這個過程就叫作「回表」
查詢數據的過程
在定位記錄所在哪一個頁時,也是通過二分法快速定位到包含該記錄的頁。定位到該頁後,又會在該頁內進行二分法快速定位記錄所在的分組(槽號),最後在分組內進行遍歷查找。
磁碟IO
磁碟處理太慢太慢了
- 儘量減少 I/O 次數,比如可以使用緩存;
- 每次 I/O 儘量獲取更多的數據;
- 每次 I/O 儘量獲取有用的數據,當然相應的也間接減少總 I/O 次數
總結:
- 數據存儲在磁碟( SSD 跟 CPU 性能也不在一個量級),而磁碟處理數據很慢;
- 提高磁碟性能主要通過減少 I/O 次數,以及單次 I/O 有效數據量;
- 索引通過多階(一個節點保存多個數據,指向多個子節點)使樹的結構更矮胖,從而減少 I/O 次數;
- 索引通過 B+ 樹,把業務數據與索引數據分離,來提高單次 I/O 有效數據量,從而減少 I/O 次數;
- 索引通過樹數據的有序和「二分查找」(多階樹可以假設為多分查找),大大縮小查詢範圍;
- 索引針對的是單個欄位或部分欄位,數據量本身比一條記錄的數據量要少的多,這樣即使通過掃描的方式查詢索引也比掃描資料庫表本身快的多;
事務
- 持久性是通過 redo log (重做日誌)來保證的;是物理日誌,記錄做了什麼修改
- 原子性是通過 undo log(回滾日誌) 來保證的;
- 一致性是binlog保證的 ,邏輯日誌(有三種格式)statement,row包含操作的具體數據,mixed
- 隔離性是通過 MVCC(多版本併發控制) 或鎖機制來保證的;
死鎖問題
處理訂單業務時,需要用到select…for update用來避免併發導致的幻讀問題,但是這樣的話就容易出現死鎖
處理方法是破壞形成死鎖的條件:打破迴圈等待條件
- 設置事務等待鎖的超時時間。當一個事務的等待時間超過該值後,就對這個事務進行回滾,於是鎖就釋放了,另一個事務就可以繼續執行了。在 InnoDB 中,參數
innodb_lock_wait_timeout
是用來設置超時時間的,預設值時 50 秒。
- 開啟主動死鎖檢測。主動死鎖檢測在發現死鎖後,主動回滾死鎖鏈條中的某一個事務,讓其他事務得以繼續執行。將參數
innodb_deadlock_detect
設置為 on,表示開啟這個邏輯,預設就開啟。
關於count
*count(1)、 count()、 count(主鍵欄位)**在執行的時候,如果表裡存在二級索引,優化器就會選擇二級索引進行掃描。
所以,如果要執行 count(1)、 count(*)、 count(主鍵欄位) 時,儘量在數據表上建立二級索引,這樣優化器會自動採用 key_len 最小的二級索引進行掃描,相比於掃描主鍵索引效率會高一些。
再來,就是不要使用 count(欄位) 來統計記錄個數,因為它的效率是最差的,會採用全表掃描的方式來統計。如果你非要統計表中該欄位不為 NULL 的記錄個數,建議給這個欄位建立一個二級索引。
優化count
如果數據量很大,因為要全表掃描,所以也要花費不短的時間
1.使用explain 出現的rows 欄位值就是 explain 命令對錶 t_order 記錄的估算值。
2.額外表保存記錄值
索引失效的情況
- 當我們使用左或者左右模糊匹配的時候,也就是
like %xx
或者like %xx%
這兩種方式都會造成索引失效; - 當我們在查詢條件中對索引列使用函數,就會導致索引失效。
- 當我們在查詢條件中對索引列進行表達式計算,也是無法走索引的。
- MySQL 在遇到字元串和數字比較的時候,會自動把字元串轉為數字,然後再進行比較。如果字元串是索引列,而條件語句中的輸入參數是數字的話,那麼索引列會發生隱式類型轉換,由於隱式類型轉換是通過 CAST 函數實現的,等同於對索引列使用了函數,所以就會導致索引失效。
- 聯合索引要能正確使用需要遵循最左匹配原則,也就是按照最左優先的方式進行索引的匹配,否則就會導致索引失效。
- 在 WHERE 子句中,如果在 OR 前的條件列是索引列,而在 OR 後的條件列不是索引列,那麼索引會失效。