MySQL常见面试题与答案
生活随笔
收集整理的這篇文章主要介紹了
MySQL常见面试题与答案
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
存儲引擎
InnoDB的主要特點是什么?
- MySQL5.5版本之后的默認存儲引擎;
- 支持事務;
- 支持行級鎖;
- 支持MVCC;
- 支持聚集索引方式存儲數據。
InnoDB與MyISAM的區別?
| 存儲結構 | MyISAM在磁盤上存儲成三個文件,其中.frm文件存儲表定義,.MYD 為數據文件,.MYI 為索引文件。 | InnoDB是由.frm文件、表空間(分為獨立表空間或者共享表空間)和日志文件(redo log)組成。 |
| 存儲空間 | 可被壓縮,存儲空間較小。 | 需要更多的內存和存儲,它會在主內存中建立其專用的緩沖池用于高速緩沖數據和索引。 |
| 事務支持 | 強調的是性能,執行速度比InnoDB快,但不支持事務。 | 支持事務,具有ACID的特性 |
| 鎖 | 只支持表級鎖。 如果執行大量的select,MyISAM是更好的選擇。但是在增刪改的時候需要鎖定整個表格,效率會低一些。 | 支持事務和行級鎖,是InnoDB的最大特色。行鎖大幅度提高了多用戶并發操作的新能。但是InnoDB的行鎖只有在WHERE條件命中索引時才是有效的,如果全表掃描會鎖定整張表。 |
| 索引 | MyISAM的索引都屬于B+Tree結構的非聚簇索引,索引與數據是分開的,B+Tree的葉子節點上存放的是數據的地址。主鍵索引和輔助索引沒有區別,只是主鍵索引必須是唯一的。 | InnoDB的主鍵是B+Tree結構的聚簇索引,將主鍵組織到一棵B+Tree中,而行數據就儲存在葉子節點上。聚簇索引是按大小排列的,因此對于范圍查詢的效率很高。InnoDB中除了主鍵索引其他輔助索引都是非聚簇索引,葉子節點則存儲的是主鍵的值,所以通過輔助索引查詢其實需要兩個過程,先確定數據的主鍵,再通過主鍵進行查詢。 |
| select count(*) | MyISAM保存了表的總行數,如果select count(*) from table不加where條件,會直接取出出該值。 | InnoDB沒有保存表的總行數,如果使用select count(*) from table就會遍歷整張表。如果加了where條件后,MyISAM和InnoDB處理的方式都一樣。 |
| 全文索引 | 支持 FULLTEXT類型的全文索引 | 不支持FULLTEXT類型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好。 |
| 外鍵 | 不支持 | 支持 |
查詢
MySQL執行一次SQL需要經過哪些流程?
注:MySQL8.0已取消查詢緩存
為什么MySQL 8.0默認關閉了緩存開啟?
EXPLAIN如何使用?
MySQL EXPLAIN屬性分析_學無止境-CSDN博客
索引
MySQL索引默認用哪種數據結構?優點是什么?
B+Tree;
優勢:
- 磁盤讀寫能力強。B+Tree非葉節點不保存數據相關信息,只保存關鍵字和子節點的引用,所以一個節點可以保存更多關鍵字,一次磁盤加載的關鍵字更多。
- 掃表能力更強。B+Tree關鍵字對應的數據都保存在葉子節點上, 進行全表掃描時,只需要遍歷葉子節點,無需遍歷整棵樹。
- 遍歷、排序、范圍搜索的能力更強。B+Tree葉子節點是順序排列的,并且相鄰節點具有順序引用的關系,所以對于這種依賴順序或范圍的操作更有優勢。
- 檢索效率更加穩定。B+Tree 永遠是在葉子節點拿到數據,所以 IO 次數是穩定的。
索引為什么不用平衡二叉樹?
- 太高:樹的高(深)度決定著它的IO操作次數。顯然,當數據量逐漸增加時,平衡二叉樹的深度也會顯著增加。
- 太小:每一個節點保存的數據量太小了。沒有很好的利用操作磁盤IO的數據交換特性,也沒有利用好磁盤IO的預讀能力(空間局部性原理),從而帶來頻繁的IO操作。
如果用Hash索引會有什么問題?
- 不適合范圍查找、排序等操作
聚簇索引和非聚簇索引的區別?
- InnoDB的主鍵是B+Tree結構的聚簇索引,將主鍵組織到一棵B+Tree中,而行數據就儲存在葉子節點上。聚簇索引是按大小排列的,因此對于范圍查詢的效率很高。
- InnoDB中除了主鍵索引其他輔助索引都是非聚簇索引,葉子節點則存儲的是主鍵的值,所以通過輔助索引查詢其實需要兩個過程,先確定數據的主鍵,再通過主鍵進行查詢。
什么是最左前綴原則?
- 對索引中關鍵字進行匹配時,一定是從左往右依次進行,不能跳過。如果最左邊是模糊的,那么將無法命中索引。
- 例如對于單列索引:a like’%123’;聯合索引 (a,b,c):where b=2 and c=3; 都無法命中索引。
- 理解了索引結構 B+Tree 的特點之后,就不難理解最左前綴原則了。
什么是覆蓋索引?
- 如果一本書需要知道第 11 章是什么標題,會翻開第 11 章對應的那一頁嗎?目錄瀏覽一下就好,這個目錄就是起到覆蓋索引的作用;
- 即通過索引便可以直接得到想要的內容,這個過程稱為覆蓋索引。
為什么MySQL選擇B+Tree索引而MongoDB卻選擇了B-Tree索引?
- B+Tree將行數據保存在葉子節點,而B-Tree的每個節點都保存數據,因此B+Tree的查詢時間復雜度固定是logn,而B-Tree查詢復雜度最好是 O(1);
- B+Tree更適合范圍查找,B-Tree單次查找的平均效率更高;
事務
ACID分別指什么?
- 原子性(Atomicity):整個事務所有操作要么全部提交成功,要么全部失敗回滾,不可能只成功一部分。
- 一致性(Consistency):事務中操作的數據及狀態改變是一致的,即寫入資料的結果必須完全符合預設的規則,不會因為出現系統意外等原因導致狀態的不一致。
- 隔離性(Isolation):通常來說,一個事務所做的修改在最終提交以前,對其它事務是不可見的。多個事務之間的操作相互不影響。
- 持久性(Durability):事務提交后,事務對數據庫的所有更新將被保存到數據庫,且無法撤回。一旦一個事務已經提交了,就算服務器崩潰,仍然需要在下次啟動的時候結合事務日志自動恢復。
事務并發下會有哪些問題?
- 臟讀:事務A讀取了事務B更新的數據,然后B回滾操作,那么A讀取到的數據是臟數據。
- 不可重復讀:事務A多次讀取同一條數據,事務B在事務A執行的過程中,對數據作了更新并提交,導致事務A多次讀取同一數據時,結果不一致。
- 幻讀:事務A對多次讀取某一范圍的數據,事務B在事務A執行的過程中插入并提交一條滿足A讀取范圍的數據,使A發現數據變多了,猶如產生幻覺一般。
事務的隔離級別有哪些?MySQL默認是哪種?
| 讀未提交(read-uncommitted) | 性能沒有明顯優勢,同時缺乏其他級別的好處,因此很少使用。 | 是 | 是 | 是 |
| 讀已提交(read-committed) | 大多數數據庫的默認級別,只能看到已提交的事務,避免了臟讀,但相同查詢可能讀到不同結果。 | 否 | 是 | 是 |
| 可重復讀(repeatable-read) | MySQL默認級別,非InnoDB可能產生幻讀。 | 否 | 否 | InnoDB 否 |
| 串行化(serializable) | 在讀取的每行數據上都加鎖,強制事務串行執行,會導致大量超時與鎖競爭問題,一般很少使用。 | 否 | 否 | 否 |
寫操作是否會阻塞讀操作,為什么?
- 不會,InnoDB引擎可以通過MVCC(多版本并發控制)實現并發訪問下,對事務內正在處理的數據做多版本管理。以實現寫操作堵塞的同時,依然可以進行讀操作。
- MVCC是基于undo log實現的,事務未提交之前,Undo log保存了未提交之前的版本數據,Undo log中的數據可作為數據舊版本快照供其他并發事務進行快照讀。
事務回滾的原理是什么?
- 在事務提交前,Undo log保存了未提交之前的版本數據,事務處理過程中如果出現了錯誤或者用戶執行了 ROLLBACK語句,MySQL可以利用Undo Log中的備份將數據恢復到事務開始之前的狀態。
如何保證的持久性?
- 持久性是通過redo log實現,MySQL會將事務中操作的最新數據備份到redo log;
- redo log可以讓數據在事務提交時以順序IO的方式快速持久化到文件,然后再異步的將這部分數據刷到具體的磁盤位置,這樣即使刷盤前發生宕機,系統重啟后也可以通過redo log來恢復數據。
鎖
InnoDB中鎖有哪些種類?
- 表鎖 & 行鎖;
- 共享鎖 & 排它鎖;
- 意向共享鎖 & 意向排它鎖:意向鎖為表級別的鎖,當事務想去進行鎖表時,可以先判斷意向鎖是否存在,存在時則可快速返回該表不能啟用表鎖;
- 自增鎖:針對自增列自增長的一個特殊的表級別鎖;
- 記錄鎖:記錄鎖鎖住的是具體的索引項;
- 臨鍵鎖:臨鍵鎖鎖住的是記錄+區間(左開右閉】,臨鍵鎖(左開右閉】可以利用B+Tree從左至右連續的特性來避免幻讀;
- 間隙鎖:間隙鎖鎖住的是數據不存在的區間(左開右開)。
什么情況下會發生死鎖?
- 多個并發事務(2個或者以上);
- 每個事務都持有鎖(或者是已經在等待鎖);
- 每個事務都需要再繼續持有鎖;
- 事務之間產生加鎖的循環等待,形成死鎖。
如何避免死鎖?
- 類似的業務邏輯以固定的順序訪問表和行;
- 大事務更傾向于死鎖,如果業務允許,將大事務拆成小事務;
- 在同一個事務中,盡可能做到一次鎖定所需要的所有資源,減少死鎖概率;
- 涉及加鎖的操作條件要索引。如果不走索引將會為表的每一行記錄添加上鎖(或者說是表鎖)。
分庫分表
常見的分片策略有哪些?
- 基于時間分片:按年、月、日等,適合存儲賬單、流水等,容易擴展,缺點是冷熱不均);
- 基于范圍分片:110000、1000020000等;
- 基于地域分片:北京、上海等;
- Hash取模分片:存儲與負載更均勻,缺點是不易擴展。
訂單表如何選擇分片鍵(買家id、商家id)?
- 可以考慮買家訂單存一份、商家訂單存一份,分別按不同字段分片(空間換時間);
- 如果重復字段多,可以考慮增加關系映射表,如訂單表按照買家id分片,買家、商家關系表按照商家id分片。
總結
以上是生活随笔為你收集整理的MySQL常见面试题与答案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 嵌入式研究杂记(1)-RISC-V开源C
- 下一篇: MySQL中实现并、交、差