日誌類型
數據類型
1.更小的通常更好
能正確存儲的最小數據類型,優點是佔用磁盤、內存和CPU都少
2.簡單就好
3.儘量避免使用null
在數據庫中null不等於null
對遊湖和索引和值的比較都很複雜
MyISAM和InnoDB存儲引擎對比
對比項 | MyISAM | InnoDB |
---|---|---|
主外鍵 | 不支持 | 支持 |
事務 | 不支持 | 支持 |
行級鎖 | 表鎖,即使操作一條記錄也會鎖住整個表,不適合高併發的操作 | 行鎖,操作時只鎖一行,不對其他行有影響,適合高併發的操作 |
緩存 | 只緩存索引,不緩存真實數據 | 不僅緩存索引還要緩存真是數據,對內存要求較高,而且內存大小對性能由決定性的影響 |
表空間 | 小 | 大 |
關注點 | 性能 | 事務 |
默認安裝 | 是 | 是 |
MySQL數據結構之最左匹配
MySQL InnoDB B+樹,葉子節點直接放置整條數據
注意:
- InnoDB是通過B+Tree結構對主鍵創建索引,然後葉子節點中存儲記錄,如果沒有主鍵,那麼會選擇唯一鍵,如果沒有唯一鍵,那麼會生成一個6字節的row_id來作爲主鍵
- 如果創建索引的鍵是其他字段,那麼在葉子節點中存儲的是該記錄的主鍵,然後再通過主鍵索引找到對應的記錄,叫做回表。簡單來說就是數據庫會再根據索引創建一個B+Tree,這個樹中存的就是索引和對應的主鍵
回表:就是上述情況,比如主鍵是id,索引列是name,這樣查找name=‘AAA’,就會是先查找name,找到後根據name對應的id,再到另一個索引樹中找到id對應的完整的一條數據
聚簇索引:數據和索引放在同一個文件中(比如:InnoDB)
非聚簇索引:數據和索引分開放在兩個文件中(比如:MyISAM)
分佈式程序不建議主鍵自增,會引發頁分裂和頁合併的問題
普通單機程序建議使用主鍵自增
回表
比如主鍵是id,並且給name添加了索引,此時數據庫會創建兩個B+Tree,如果執行select * from table where name = ?,會先在name和id的樹中找到id,再用id在另一個樹中找到整條數據,這就是回表
索引覆蓋
上述情況中,如果查詢select id from table where name = ?,直接查詢一個樹就能得到結果,不用回表就叫索引覆蓋
索引下推
select * from table where name = ?and age = ?
這條語句執行的話,會從磁盤先查出符合name = ?的所有數據,加入到mysql server中,再根據age進行篩選
有了索引下推後,會根據name和age來拉取數據,不用在server層做數據的篩選
最左匹配
組合索引,比如name+age,一定是先匹配name再匹配age
舉例:
- where name = ? and age = ?
- where name = ?
- where age = ?
- where age = ? and name = ?
上述例子中1,2,4會使用索引,4會經過優化成爲1
CBO:基於成本的優化
RBO:基於效率的優化
索引下推唯一的缺點是需要在磁盤上多做數據篩選,原來的篩選是放在內存中的,現在放到了磁盤查找數據,並且所有的數據是聚集存放,所以性能不會有影響,而且整體的IO量會大大減少,反而會提升性能
MySQL中的一些名詞和概念
MRR:
全稱是mult_range read
在內存中做排序
FIC
全稱是fast index create
沒有FIC時索引的修改過程:
- 先創建一個臨時表,增刪改的操作在臨時表中操作
- 刪除原始索引表
- 修改臨時表替換原始表
有了FIC後的索引修改過程:
FIC給當前表添加一個share鎖,不會有創建臨時文件的資源消耗,還是在源文件中,但是此時如果有人發起DML操作,很明顯數據完全不一致,所以添加share鎖,讀取沒問題,但是DML會有問題
這部分名詞和概念還需要仔細百度一下
索引分類
- 主鍵索引:主鍵
- 唯一索引:值唯一的列
- 普通索引:也叫輔助索引、二級索引,除了主鍵和唯一列以外的創建了索引的列
- 全文索引:很少使用,被ES搜索引擎取代
- 組合索引:多個字段組合的索引
引匹配方式
- 全值匹配:組合索引中的所有的列進行匹配
- 匹配最左前綴:只匹配前面的幾列
- 匹配列前綴:可以匹配某一列的開頭部分(like A%可以正常匹配,like %A則會導致索引失效)
- 匹配範圍值:可以查找某一個範圍的數據
- 精確匹配某一列並範圍匹配另一列:可以查詢第一列的全部值和第二列的部分值
- 只訪問索引列:查詢的時候值需要訪問索引,不需要訪問數據行,本質上i就是索引覆蓋
哈希索引
索引優化的小細節
索引監控
MySQL基礎知識
MySQL索引詳解