MySQL面試問答片段(總結分享)

WBOY
發布: 2022-03-22 17:45:07
轉載
2226 人瀏覽過

這篇文章為大家帶來了關於mysql的相關知識,其中主要整理了一些面試常會問到的題目,包括了資料庫架構、索引和SQL優化等等,希望對大家有幫助。

MySQL面試問答片段(總結分享)

推薦學習:mysql教學

#1、資料庫架構

1.1、說說MySQL 的基礎架構圖片

跟面試官講一下MySQL 的邏輯架構,有白板可以把下面的圖畫一下,圖片來自網路。

MySQL面試問答片段(總結分享)

Mysql邏輯架構圖主要分三層:

#(1)第一層負責連線處理,授權認證,安全性等等 

#(2)第二層負責編譯並最佳化SQL 

(3)第三層是儲存引擎。

1.2、一條SQL查詢語句在MySQL中如何執行的?

  • 先檢查該語句是否有權限,如果沒有權限,直接傳回錯誤訊息,如果有權限會先查詢快取(MySQL8.0 版本之前)。

  • 如果沒有緩存,分析器進行詞法分析,提取sql 語句中select 等關鍵元素,然後判斷sql 語句是否有語法錯誤,例如關鍵字是否正確等等。

  • 最後優化器決定執行方案進行權限校驗,如果沒有權限就直接傳回錯誤訊息,如果有權限就會呼叫資料庫引擎介面,回傳執行結果。

2、SQL 最佳化

2.1、日常工作中你是怎麼優化SQL的?

可以從這幾個維度回答這個問題:

2.1.1、優化表格結構

(1)盡量使用數字型欄位

若只包含數值資訊的欄位盡量不要設計為字元型,這會降低查詢和連接的效能,並會增加儲存開銷。這是因為引擎在處理查詢和連接時會逐個比較字串中每一個字符,而對於數字型而言只需要比較一次就夠了。

(2)盡可能的使用 varchar 取代 char

變長欄位儲存空間小,可以節省儲存空間。

(3)當索引列大量重複資料時,可以把索引刪除掉

例如有一列是性別,幾乎只有男、女、未知,這樣的索引是無效的。

2.1.2、最佳化查詢

  • #應盡量避免在where 子句中使用!=或運算子

  • 應盡量避免在where 子句中使用or 來連接條件

  • #任何查詢也不要出現select *

  • 避免在where 子句中對欄位進行null 值判斷

2.1.3、索引最佳化

  • 對作為查詢條件和order by的欄位建立索引

  • 避免建立過多的索引,多使用組合索引

2.2、怎麼看執行計劃(explain),如何理解其中各個字段的含義?

在 select 語句之前增加 explain 關鍵字,會傳回執行計劃的資訊。

MySQL面試問答片段(總結分享)

(1)id 欄位:是 select 語句的序號,MySQL將 select 查詢分為簡單查詢和複雜查詢。

(2)select_type列:表示對應行是簡單還是複雜的查詢。

(3)table 欄位:表示 explain 的一行正在存取哪個資料表。

(4)type 欄位:最重要的欄位之一。表示關聯類型或存取類型,即 MySQL 決定如何查找表中的行。從最優到最差分別是:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

#(index_subquery > range > index > ALL

( 5)possible_keys 欄位:顯示查詢可能使用哪些索引來尋找。

(6)key 欄位:這一列顯示 mysql 實際上採用哪個索引來最佳化對該資料表的存取。

(7)key_len 欄位:顯示了mysql在索引裡使用的位元組數,透過這個值可以算出具體使用了索引中的哪些欄位。

(8)ref 欄位:這一列顯示了在key列記錄的索引中,表查找值所用到的列或常數,常見的有:const(常數),func,NULL,欄位名稱。

(9)rows 欄位:這一列是 mysql 估計要讀取並偵測的行數,注意這個不是結果集裡的行數。

(10)Extra 欄位:顯示額外資訊。例如有 Using index、Using where、Using temporary等。

2.3、關心過業務系統裡面的sql耗時嗎?統計過慢查詢嗎?對慢查詢都怎麼優化過?

我們平常寫Sql時,都要養成用explain分析的習慣。慢查詢的統計,維運會定期統計給我們

優化慢查詢思路:

  • #分析語句,是否載入了不必要的欄位/資料

  • 分析SQL 執行句話,是否命中索引等

  • 如果SQL 很複雜,最佳化SQL 結構

  • 如果表資料量太大,考慮分錶

3、索引

#3.1、聚集索引與非聚集索引的區別

#可以按以下四個維度回答:

(1)一個表格中只能擁有一個聚集索引,而非聚集索引一個表格可以存在多個。

(2)聚集索引,索引中鍵值的邏輯順序決定了表中對應行的物理順序;非聚集索引,索引中索引的邏輯順序與磁碟上行的物理儲存順序不同。

(3)索引是透過二元樹的資料結構來描述的,我們可以這麼理解叢集索引:索引的葉節點就是資料節點。而非聚集索引的葉節點仍然是索引節點,只不過有一個指標指向對應的資料塊。

(4)聚集索引:實體儲存依照索引排序;非聚集索引:實體儲存不依照索引排序;

3.2、為什麼要用 B 樹,為什麼不用普通二元樹?

可以從幾個維度去看這個問題,查詢是否夠快,效率是否穩定,儲存資料多少,以及查找磁碟次數,為什麼不是普通二元樹,為什麼不是平衡二元樹,為什麼不是B樹,而偏偏是B 樹呢?

3.2.1、為什麼不是普通二元樹?

如果二元樹特殊化為一個鍊錶,相當於全表掃描。平衡二元樹相比於二元查找樹來說,查找效率更穩定,整體的查找速度也更快。

3.2.2、為什麼不是平衡二元樹呢?

我們知道,在記憶體比在磁碟的數據,查詢效率快得多。如果樹這種資料結構作為索引,那我們每查找一次資料就需要從磁碟中讀取一個節點,也就是我們說的一個磁碟區塊,但是平衡二元樹可是每個節點只儲存一個鍵值和資料的,如果是B樹,可以儲存更多的節點數據,樹的高度也會降低,因此讀取磁碟的次數就降下來啦,查詢效率就快啦。

3.2.3、為什麼不是 B 樹而是 B 樹呢?

B 樹非葉節點上是不儲存資料的,僅儲存鍵值,而B樹節點中不僅儲存鍵值,也會儲存資料。 innodb中頁的預設大小是16KB,如果不儲存數據,那麼就會儲存更多的鍵值,相應的樹的階數(節點的子節點樹)就會更大,樹就會更矮更胖,如此一來我們查找資料進行磁碟的IO次數有會再次減少,資料查詢的效率也會更快。

B 樹索引的所有資料都儲存在葉子節點,而且資料是按照順序排列的,鍊錶連著的。那麼 B 樹使得範圍查找,排序查找,分組查找以及去重查找變得異常簡單。

3.3、Hash 索引和 B 樹索引差異是什麼?你在設計索引是怎麼抉擇的?

  • B 樹可以進行範圍查詢,Hash 索引不能。

  • B 樹支援聯合索引的最左邊原則,Hash 索引不支援。

  • B 樹支援 order by 排序,Hash 索引不支援。

  • Hash 索引在等值查詢上比 B 樹更有效率。

  • B 樹使用 like 進行模糊查詢的時候,like 後面(例如%開頭)的話可以起到優化的作用,Hash 索引根本無法進行模糊查詢。

3.4、什麼是最左字首原則?什麼是最左匹配原則?

最左前綴原則,就是最左優先,在建立多列索引時,要根據業務需求,where 子句中使用最頻繁的一列放在最左邊。

當我們建立一個組合索引的時候,如(a1,a2,a3),相當於創建了(a1)、(a1,a2)和(a1,a2,a3)三個索引,這就是最左匹配原則。

3.5、索引不適合哪些場景?

  • 資料量少的不適合加上索引

  • 更新比較頻繁的也不適合加索引= 區分度低的欄位不適合加索引(如性別)

3.6、索引有哪些優缺點?

(1) 優點:

  • 唯一索引可以保證資料庫表中每一行的資料的唯一性

  • 可以加快資料查詢速度,減少查詢時間

(2)缺點:

  • 建立索引和維護索引要耗費時間

  • 索引需要佔物理空間,除了資料表佔用資料空間之外,每個索引還要佔用一定的物理空間

  • 以表中的數據進行增、刪、改的時候,索引也要動態的維護。

4、鎖定

4.1、MySQL 遇過死鎖問題嗎,你是如何解決的?

遇過。我排查死鎖的一般步驟是醬紫的:

(1)查看死鎖日誌show engine innodb status;

(2)找出死鎖Sql

(3)分析sql加鎖情況

( 4)模擬死鎖案發

(5)分析死鎖日誌

(6)分析死鎖結果

4.2、說說資料庫的樂觀鎖和悲觀鎖是什麼以及它們的差異?

(1)悲觀鎖:

悲觀鎖她專一且缺乏安全感了,她的心只屬於當前事務,每時每刻都擔心著它心愛的數據可能被別的事務修改,所以一個事務擁有(獲得)悲觀鎖後,其他任何事務都不能對資料進行修改啦,只能等待鎖被釋放才可以執行。

(2)樂觀鎖:

樂觀鎖的「樂觀情緒」體現在,它認為資料的變動不會太頻繁。因此,它允許多個事務同時對資料進行變動。

實作方式:樂觀鎖一般會使用版本號機製或CAS演算法實作。

4.3、MVCC 熟悉嗎,知道它的底層原理?

MVCC (Multiversion Concurrency Control),即多版本並發控制技術。

MVCC在MySQL InnoDB中的實作主要是為了提高資料庫並發效能,用更好的方式去處理讀取-寫入衝突,做到即使有讀寫衝突時,也能做到不加鎖,非阻塞並發讀。

5、事務

5.1、MySQL事務得四大特性以及實作原則

  • 原子性:事務作為一個整體被執行,包含在其中的對資料庫的操作要麼全部被執行,要麼都不執行。

  • 一致性:指在事務開始之前和事務結束以後,資料不會被破壞,假如A帳戶給B帳戶轉10塊錢,不管成功與否,A和B的總金額是不變的。

  • 隔離性:多個交易並發存取時,交易之間是相互隔離的,即一個交易不影響其它交易運作效果。簡言之,就是事務之間是進水不犯河水的。

  • 持久性:表示交易完成以後,該交易對資料庫所做的操作更改,將持久地保存在資料庫之中。

5.2、交易的隔離等級有哪些? MySQL的預設隔離等級是什麼?

  • 讀取未提交(Read Uncommitted)

  • #已提交(Read Committed)

#可重複讀取(Repeatable Read)

串行化(Serializable)

Mysql預設的交易隔離等級是可重複讀取(Repeatable Read )

5.3、什麼是幻讀,髒讀,不可重複讀呢?

事務A、B交替執行,事務A被事務B幹擾到了,因為事務A讀取到事務B未提交的數據,這就是髒讀。

在一個事務範圍內,兩個相同的查詢,讀取同一筆記錄,卻回傳了不同的數據,這就是不可重複讀取。

事務A查詢一個範圍的結果集,另一個並發事務B往這個範圍中插入/刪除了數據,並靜悄悄地提交,然後事務A再次查詢相同的範圍,兩次讀取得到的結果集不一樣了,這就是幻讀。

6、實戰

6.1、MySQL資料庫cpu飆漲的話,要怎麼處理呢?

排查過程:

(1)使用top 指令觀察,確定是mysqld導致還是其他原因。

(2)如果是mysqld導致的,show processlist,查看session情況,確定是不是有消耗資源的sql在運作。

(3)找出消耗高的 sql,看看執行計畫是否準確, 索引是否缺失,資料量是否太大。

MySQL面試問答片段(總結分享)處理:

    (1)kill 掉這些執行緒(同時觀察cpu 使用率是否下降)
  • (2)進行對應的調整(比如說加索引、改sql、改記憶體參數)

  • (3)重新跑這些SQL。
  • 其他情況:

  • 也有可能是每個sql 消耗資源並不多,但是突然之間,有大量的session 連進來導致cpu 飆升,這種情況就需要跟應用一起來分析為何連線數會激增,再做出對應的調整,比如說限制連線數等
  • 6.2、MYSQL的主從延遲,你怎麼解決?

  • 主從複製分了五個步驟進行:(圖片來自網路)

步驟一:主庫的更新事件(update、insert、delete)被寫到binlog

步驟二:從庫發起連接,連接到主庫。 ############步驟三:此時主庫建立一個binlog dump thread,把binlog的內容傳送到從庫。 ############步驟四:從庫啟動之後,建立一個I/O線程,讀取主庫傳過來的binlog內容並寫入到relay log######## ####步驟五:也會建立一個SQL線程,從relay log裡面讀取內容,從Exec_Master_Log_Pos位置開始執行讀取到的更新事件,將更新內容寫入到slave的db######## ########主從同步延遲的原因######

一個伺服器開放N個連結給客戶端來連接的,這樣有會有大並發的更新操作, 但是從伺服器的里面讀取binlog的線程僅有一個,當某個SQL在從伺服器上執行的時間稍長或因為某個SQL要進行鎖定表就會導致,主伺服器的SQL大量積壓,並未同步到從伺服器。這就導致了主從不一致, 也就是主從延遲。

主從同步延遲的解決方法

  • 主伺服器要負責更新操作,對安全性的要求比從伺服器要高,所以有些設定參數可以修改,例如sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之類的設定等。

  • 選擇更好的硬體設備作為slave。

  • 把一台從伺服器當度當作備份使用, 而不提供查詢, 那邊他的負載下來了, 執行relay log 裡面的SQL效率自然就高了。

  • 增加從伺服器嘍,這個目的還是分散讀取的壓力,進而降低伺服器負載。

6.3、如果讓你做分庫與分錶的設計,簡單說說你會怎麼做?

分庫分錶方案:

  • 水平分庫:以欄位為依據,依照一定策略(hash、range等),將一個庫中的資料拆分到多個庫中。

  • 水平分錶:以欄位為依據,依照某一策略(hash、range等),將一個表中的資料分割到多個表中。

  • 垂直分庫:以表為依據,依業務歸屬不同,將不同的表拆分到不同的庫中。

  • 垂直分錶:以欄位為依據,依照欄位的活躍性,將表格中欄位拆到不同的資料表(主表和擴充表)。

常用的分庫分錶中間件:

  • sharding-jdbc

  • Mycat

分庫分錶可能遇到的問題

  • 交易問題:需要用分佈式事務啦

  • 跨節點Join的問題:解決這一問題可以分兩次查詢實現

  • 跨節點的count,order by ,group by以及聚合函數問題:分別在各個節點上得到結果後在應用程式端進行合併。

  • 資料遷移,容量規劃,擴容等問題

  • #ID問題:資料庫被切分後,不能再依賴資料庫本身的主鍵生成機制啦,最簡單可以考慮UUID

  • 跨分片的排序分頁問題

推薦學習:mysql學習教學

以上是MySQL面試問答片段(總結分享)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:csdn.net
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板