MySQL 面試篇

MySQL相關面試題

在這里插入圖片描述

定位慢查詢

**面試官:**MySQL中,如何定位慢查詢?

我們當時做壓測的時候有的接口非常的慢,接口的響應時間超過了2秒以上,因為我們當時的系統部署了運維的監控系統Skywalking ,在展示的報表中可以看到是哪一個接口比較慢,并且可以分析這個接口哪部分比較慢,這里可以看到SQL的具體的執行時間,所以可以定位是哪個sql出了問題。

如果,項目中沒有這種運維的監控系統,其實在MySQL中也提供了慢日志查詢的功能,可以在MySQL的系統配置文件中開啟這個慢日志的功能,并且也可以設置SQL執行超過多少時間來記錄到一個日志文件中,我記得上一個項目配置的是2秒,只要SQL執行的時間超過了2秒就會記錄到日志文件中,我們就可以在日志文件找到執行比較慢的SQL了。

**面試官:**那這個SQL語句執行很慢, 如何分析呢?

如果一條sql執行很慢,我們通常會使用mysql自動的執行計劃explain來去查看這條sql的執行情況,比如在這里面可以通過key和key_len檢查是否命中了索引,如果本身已經添加了索引,也可以判斷索引是否有失效的情況。第二個,可以通過type字段查看sql是否有進一步的優化空間,是否存在全索引掃描或全盤掃描,第三個可以通過extra建議來判斷,是否出現了回表的情況,如果出現了,可以嘗試添加索引或修改返回字段來修復。

索引

**面試官:**了解過索引嗎?(什么是索引)

索引在項目中還是比較常見的,它是幫助MySQL高效獲取數據的數據結構,主要是用來提高數據檢索的效率,降低數據庫的IO成本,同時通過索引列對數據進行排序,降低數據排序的成本,也能降低了CPU的消耗。

**面試官:**索引的底層數據結構了解過嘛 ?

MySQL的默認的存儲引擎InnoDB采用的B+樹的數據結構來存儲索引,選擇B+樹的主要的原因是:第一階數更多,路徑更短。第二個磁盤讀寫代價B+樹更低,非葉子節點只存儲指針,葉子階段存儲數據。第三是B+樹便于掃庫和區間查詢,葉子節點是一個雙向鏈表。

**面試官:**B樹和B+樹的區別是什么呢?

第一:在B樹中,非葉子節點和葉子節點都會存放數據,而B+樹的所有的數據都會出現在葉子節點,在查詢的時候,B+樹查找效率更加穩定

第二:在進行范圍查詢的時候,B+樹效率更高,因為B+樹都在葉子節點存儲,并且葉子節點是一個雙向鏈表

**面試官:**索引創建原則有哪些?

這個情況有很多,不過都有一個大前提,就是表中的數據要超過10萬以上,我們才會創建索引,并且添加索引的字段是查詢比較頻繁的字段,一般也是像作為查詢條件,排序字段或分組的字段這些。

還有就是,我們通常創建索引的時候都是使用復合索引來創建,一條sql的返回值,盡量使用覆蓋索引,如果字段的區分度不高的話,我們也會把它放在組合索引后面的字段。

如果某一個字段的內容較長,我們會考慮使用前綴索引來使用,當然并不是所有的字段都要添加索引,這個索引的數量也要控制,因為添加索引也會導致新增改的速度變慢。

**面試官:**什么情況下索引會失效 ?

  1. 索引在使用的時候沒有遵循最左匹配法則,
  2. 模糊查詢,如果%號在前面也會導致索引失效。
  3. 添加索引的字段上進行了運算操作或者類型轉換也都會導致索引失效。
  4. 如果使用了復合索引,中間使用了范圍查詢,右邊的條件索引也會失效。

所以,通常情況下,想要判斷出這條sql是否有索引失效的情況,可以使用explain執行計劃來分析。

聚集索引&二級索引

**面試官:**什么是聚簇索引什么是非聚簇索引 ?

聚簇索引:數據與索引放到一塊,B+樹的葉子節點保存了整行數據,有且只有一個,一般情況下主鍵在作為聚簇索引的。

非聚簇索引:數據與索引分開存儲,B+樹的葉子節點保存對應的主鍵,可以有多個,一般我們自己定義的索引都是非聚簇索引。

回表查詢

**面試官:**知道什么是回表查詢嘛 ?

剛才介紹的聚簇索引和非聚簇索引是有關系的,回表的意思就是通過二級索引找到對應的主鍵值,然后再通過主鍵值找到聚集索引中所對應的整行數據,這個過程就是回表。

備注:如果面試官直接問回表,則需要先介紹聚簇索引和非聚簇索引】

**面試官:**知道什么叫覆蓋索引嘛 ?

覆蓋索引是指select查詢語句使用了索引,在返回的列,必須在索引中全部能夠找到。

如果我們使用id查詢,它會直接走聚集索引查詢,一次索引掃描,直接返回數據,性能高。

如果按照二級索引查詢數據的時候,返回的列中沒有創建索引,有可能會觸發回表查詢,盡量避免使用select *,盡量在返回的列中都包含添加索引的字段。

**面試官:**MYSQL超大分頁怎么處理 ?

超大分頁一般都是在數據量比較大時,我們使用了limit分頁查詢,并且需要對數據進行排序,這個時候效率就很低,我們可以采用覆蓋索引 + 子查詢來解決。

先分頁查詢數據的id字段,確定了id之后,再用子查詢來過濾,只查詢這個id列表中的數據就可以了。

因為查詢id的時候,走的覆蓋索引,所以效率可以提升很多

SQL優化

**面試官:**sql的優化的經驗

  1. 表的設計優化,數據類型的選擇
  2. 索引優化,索引創建原則
  3. sql語句優化,避免索引失效(不要使用select * …)
  4. 主從復制,讀寫分離,不讓數據的寫入,影響讀操作
  5. 分庫分表

**面試官:**創建表的時候,你們是如何優化的呢?

我們主要參考的阿里出的那個開發手冊《嵩山版》,就比如,在定義字段的時候需要結合字段的內容來選擇合適的類型,如果是數值的話,像tinyint、int 、bigint這些類型,要根據實際情況選擇。如果是字符串類型,也是結合存儲的內容來選擇char和varchar或者text類型。

**面試官:**那在使用索引的時候,是如何優化呢?

【參考索引創建原則 進行描述】

**面試官:**你平時對sql語句做了哪些優化呢?

這個也有很多,比如SELECT語句務必指明字段名稱,不要直接使用select * ,還有就是要注意SQL語句避免造成索引失效的寫法;如果是聚合查詢,盡量用union all代替union ,union會多一次去重過濾,效率比較低;如果是表關聯的話,盡量使用innerjoin ,不要使用用left join right join,如必須使用 一定要以小表為驅動

事務

**面試官:**事務的特性是什么?可以詳細說一下嗎?

ACID,分別指的是:原子性、一致性、隔離性、持久性;

  • 原子性(Atomicity):事務是不可分割的最小操作單元,要么全部成功,要么全部失敗。
  • 一致性(Consistency):事務完成時,必須使所有的數據都保持一致狀態。
  • 隔離性(Isolation):數據庫系統提供的隔離機制,保證事務在不受外部并發操作影響的獨立環境下運行。
  • 持久性(Durability):事務一旦提交或回滾,它對數據庫中的數據的改變就是永久的。

我舉個例子:A向B轉賬500,轉賬成功,A扣除500元,B增加500元,原子操作體現在要么都成功,要么都失敗。

在轉賬的過程中,數據要一致,A扣除了500,B必須增加500。

在轉賬的過程中,隔離性體現在A像B轉賬,不能受其他事務干擾。

在轉賬的過程中,持久性體現在事務提交后,要把數據持久化。

面試官:并發事務帶來哪些問題?

我們在項目開發中,多個事務并發進行是經常發生的,并發也是必然的,有可能導致一些問題

  1. 臟讀:一個事務讀到了另一個事務還沒有提交的數據。比如當一個事務正在訪問數據并且對數據進行了修改,而這種修改還沒有提交到數據庫中,這時另外一個事務也訪問了這個數據,因為這個數據是還沒有提交的數據,那么另外一個事務讀到的這個數據是“臟數據”,依據“臟數據”所做的操作可能是不正確的。

  2. 不可重復讀:一個事務先后讀到同一條記錄,但兩個讀取的數據不同。比如在一個事務內多次讀同一數據。在這個事務還沒有結束時,另一個事務也訪問該數據。那么,在第一個事務中的兩次讀數據之間,由于第二個事務的修改導致第一個事務兩次讀取的數據可能不太一樣。這就發生了在一個事務內兩次讀到的數據是不一樣的情況,因此稱為不可重復讀。

  3. 幻讀:一個事務查詢數據時,沒有該數據,但是插入數據時,又發現這行數據已經存在,好像出現了“幻影”。它發生在一個事務(T1)讀取了幾行數據,接著另一個并發事務(T2)插入了一些數據時。在隨后的查詢中,第一個事務(T1)就會發現多了一些原本不存在的記錄,就好像發生了幻覺一樣,所以稱為幻讀。

面試官:怎么解決這些問題呢?MySQL的默認隔離級別是?

解決方案是對事務進行隔離。MySQL支持四種隔離級別從低到高分別有:

  1. 未提交讀(read uncommitted)它解決不了剛才提出的所有問題,一般項目中也不用這個。
  2. 讀已提交(read committed)它能解決臟讀的問題的,但是解決不了不可重復讀和幻讀。
  3. 可重復讀(repeatable read)它能解決臟讀和不可重復讀,但是解決不了幻讀,這個也是mysql默認的隔離級別。
  4. 串行化(serializable)它可以解決剛才提出來的所有問題,但是由于讓是事務串行執行的,性能比較低。

注意:事務隔離級別越高,數據越安全,但是性能越低。所以,我們一般使用的都是mysql默認的隔離級別:可重復讀

面試官:undo log和redo log的區別

redo log日志記錄的是數據頁的物理變化,服務宕機可用來同步數據。

undo log 不同,它主要記錄的是邏輯日志,當事務回滾時,通過逆操作恢復原來的數據,比如我們刪除一條數據的時候,就會在undo log日志文件中新增一條delete語句,如果發生回滾就執行逆操作。

redo log保證了事務的持久性,undo log保證了事務的原子性和一致性。

面試官:事務中的隔離性是如何保證的呢?(你解釋一下MVCC)

事務的隔離性是由鎖和mvcc實現的。

其中mvcc的意思是多版本并發控制。指維護一個數據的多個版本,使得讀寫操作沒有沖突,它的底層實現主要是分為了三個部分,第一個是隱藏字段,第二個是undo log日志,第三個是readView讀視圖。

隱藏字段是指:在mysql中給每個表都設置了隱藏字段,有一個是trx_id(事務id),記錄每一次操作的事務id,是自增的;另一個字段是roll_pointer(回滾指針),指向上一個版本的事務版本記錄地址。

undo log主要的作用是記錄回滾日志,存儲老版本數據,在內部會形成一個版本鏈,在多個事務并行操作某一行記錄,記錄不同事務修改數據的版本,通過roll_pointer指針形成一個鏈表。

readView解決的是一個事務查詢選擇版本的問題,在內部定義了一些匹配規則和當前的一些事務id判斷該訪問那個版本的數據,不同的隔離級別快照讀是不一樣的,最終的訪問的結果不一樣。如果是rc隔離級別,每一次執行快照讀時生成ReadView,如果是rr隔離級別僅在事務中第一次執行快照讀時生成ReadView,后續復用。

面試官:MySQL主從同步原理

在這里插入圖片描述

MySQL主從復制的核心就是二進制日志(DDL(數據定義語言)語句和 DML(數據操縱語言)語句),步驟如下:
在這里插入圖片描述

  1. 主庫在事務提交時,會把數據變更記錄在二進制日志文件 Binlog 中。

  2. 從庫讀取主庫的二進制日志文件 Binlog ,寫入到從庫的中繼日志 Relay Log 。

  3. 從庫重做中繼日志中的事件,將改變反映它自己的數據

面試官:你們項目用過MySQL的分庫分表嗎?

嗯,因為我們都是微服務開發,每個微服務對應了一個數據庫,是根據業務進行拆分的,這個其實就是垂直拆分。

面試官:那你之前使用過水平分庫嗎?

這個是使用過的,我們當時的業務是(xxx),一開始,我們也是單庫,后來這個業務逐漸發展,業務量上來的很迅速,其中(xx)表已經存放了超過1000萬的數據,我們做了很多優化也不好使,性能依然很慢,所以當時就使用了水平分庫。

我們一開始先做了3臺服務器對應了3個數據庫,由于庫多了,需要分片,我們當時采用的mycat來作為數據庫的中間件。數據都是按照id(自增)取模的方式來存取的。

當然一開始的時候,那些舊數據,我們做了一些清洗的工作,我們也是按照id取模規則分別存儲到了各個數據庫中,好處就是可以讓各個數據庫分攤存儲和讀取的壓力,解決了我們當時性能的問題。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/72777.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/72777.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/72777.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MyBatis 操作數據庫

目錄 1、MyBatis 是什么2、配置 MyBatis 開發環境2.1、添加 MyBatis 框架支持2.1.1、老項目添加 MyBatis2.1.2、新項目添加 MyBatis 2.2、配置數據庫連接字符串2.3、配置 MyBatis 中的 XML 路徑 3、添加業務代碼3.1、添加實體類3.2、添加 mapper 接口3.3、添加 xml 文件3.4、添…

uniapp使用藍牙,usb,局域網,打印機打印

使用流程(支持安卓和iOS) 引入SDK 引入原生插件包地址如下 https://github.com/oldfive20250214/UniPrinterDemo 連接設備 安卓支持經典藍牙、ble藍牙、usb、局域網(參考API) iOS支持ble藍牙、局域網(參考API&…

Jmeter進行http接口測試詳解

🍅 點擊文末小卡片,免費獲取軟件測試全套資料,資料在手,漲薪更快 本文主要針對http接口進行測試,使用 jmeter工具實現。 Jmeter工具設計之初是用于做性能測試的,它在實現對各種接口的調用方面已經做的比較…

力扣35.搜索插入位置-二分查找

class Solution:def searchInsert(self, nums: List[int], target: int) -> int:# 初始化左右指針left, right 0, len(nums) - 1# 當左指針小于等于右指針時&#xff0c;繼續循環while left < right:# 計算中間位置mid (left right) // 2# 如果中間元素等于目標值&…

為AI聊天工具添加一個知識系統 之133 詳細設計之74通用編程語言 之4 架構及其核心

本篇繼續討論 通用編程語言。 說明&#xff1a;本階段的所有討論都是圍繞這一主題展開的&#xff0c;但前面的討論分成了三個大部分&#xff08;后面列出了這一段的討論題目的歸屬關系&#xff09;-區別distinguish&#xff08;各別&#xff09;&#xff1a; 文化和習俗。知識…

PPT 技能:巧用 “節” 功能,讓演示文稿更有序

在制作PPT時&#xff0c;你是否遇到過這樣的情況&#xff1a;幻燈片越來越多&#xff0c;內容越來越雜&#xff0c;找某一頁內容時翻得眼花繚亂&#xff1f;尤其是在處理大型PPT文件時&#xff0c;如果沒有合理的結構&#xff0c;編輯和調整都會變得非常麻煩。這時候&#xff0…

劉火良 FreeRTOS內核實現與應用之1——列表學習

重要數據 節點的命名都以_ITEM后綴進行&#xff0c;鏈表取消了后綴&#xff0c;直接LIST 普通的節點數據類型 /* 節點結構體定義 */ struct xLIST_ITEM { TickType_t xItemValue; /* 輔助值&#xff0c;用于幫助節點做順序排列 */ struct xLIST_I…

Uniapp項目運行到微信小程序、H5、APP等多個平臺教程

摘要&#xff1a;Uniapp作為一款基于Vue.js的跨平臺開發框架&#xff0c;支持“一次開發&#xff0c;多端部署”。本文將手把手教你如何將Uniapp項目運行到微信小程序、H5、APP等多個平臺&#xff0c;并解析常見問題。 一、環境準備 在開始前&#xff0c;請確保已安裝以下工具…

100天精通Python(爬蟲篇)——第115天:爬蟲在線小工具_Curl轉python爬蟲代碼工具(快速構建初始爬蟲代碼)

文章目錄 一、curl是什么&#xff1f;二、爬蟲在線小工具&#xff08;牛逼puls&#xff09;三、實戰操作 一、curl是什么&#xff1f; 基本概念&#xff1a;curl 支持多種協議&#xff0c;如 HTTP、HTTPS、FTP、SFTP 等&#xff0c;可用于從服務器獲取數據或向服務器發送數據&a…

[內網安全] Windows 域認證 — Kerberos 協議認證

&#x1f31f;想系統化學習內網滲透&#xff1f;看看這個&#xff1a;[內網安全] 內網滲透 - 學習手冊-CSDN博客 0x01&#xff1a;Kerberos 協議簡介 Kerberos 是一種網絡認證協議&#xff0c;其設計目標是通過密鑰系統為客戶機 / 服務器應用程序提供強大的認證服務。該認證過…

PyTorch中的損失函數:F.nll_loss 與 nn.CrossEntropyLoss

文章目錄 背景介紹F.nll_loss什么是負對數似然損失&#xff1f;應用場景 nn.CrossEntropyLoss簡化工作流程內部機制 區別與聯系 背景介紹 無論是圖像分類、文本分類還是其他類型的分類任務&#xff0c;交叉熵損失&#xff08;Cross Entropy Loss&#xff09;都是最常用的一種損…

案例1_3:流水燈

文章目錄 文章介紹原理圖&#xff08;同案例1_2&#xff09;代碼效果圖 文章介紹 原理圖&#xff08;同案例1_2&#xff09; 代碼 #include <reg51.h> // 包含頭文件void delay(unsigned int time) {unsigned int i, j;for (i 0; i < time; i)for (j 0; j < 1…

基于物聯網技術的電動車防盜系統設計(論文+源碼)

1總體設計 本課題為基于物聯網技術的電動車防盜系統&#xff0c;在此將整個系統架構設計如圖2.1所示&#xff0c;其采用STM32F103單片機為控制器&#xff0c;通過NEO-6M實現GPS定位功能&#xff0c;通過紅外傳感器檢測電瓶是否離開位&#xff0c;通過Air202 NBIOT模塊將當前的數…

學習知識的心理和方法雜記-02

本文簡單記錄下我個人對大腦學習模式的認識。 人腦的基本能力是什么&#xff1f; 接收輸入的能力。語言和聲音 視覺圖像 觸覺 嗅覺 味覺等。 存儲能力。人腦存儲能力背后的物理化學結構我們人類目前還無法完全認知&#xff0c;但是存儲的目標物一定是人可以通過五官獲得的形…

國產化替換案例:CACTER郵件網關為Groupwise系統加固郵件安全防線

電子郵件作為企業信息流轉的命脈&#xff0c;承載著商業機密與客戶數據。然而&#xff0c;網絡攻擊手段日益復雜&#xff0c;釣魚郵件等威脅正快速侵蝕企業安全防線。據《2024年第四季度企業郵箱安全性研究報告》顯示&#xff0c;2024年Q4企業郵箱用戶遭遇的釣魚郵件數量激增至…

3.使用ElementUI搭建側邊欄及頂部欄

1. 安裝ElementUI ElementUI是基于 Vue 2.0 的桌面端組件庫。使用之前&#xff0c;需要在項目文件夾中安裝ElementUI&#xff0c;在終端中輸入以下命令&#xff0c;進行安裝。 npm i element-ui -S并在main.js中引入ElementUI 2. 使用elmentUI組件進行頁面布局 2.1 清空原…

C++并發以及多線程的秘密

1.基礎概念 并發&#xff08;Concurrency&#xff09; 并發是指在同一時間段內&#xff0c;多個任務看起來像是同時執行的。并發并不一定意味著真正的同時執行&#xff0c;它可以是通過時間片輪轉等方式在多個任務之間快速切換&#xff0c;讓用戶感覺多個任務在同時進行。并發…

從零開始實現大語言模型(十四):高階訓練技巧

1. 前言 預訓練大語言模型的流程與訓練普通神經深度網絡模型本質上并沒有任何不同。可以使用深度學習實踐中已經被證明非常有效的高階訓練技巧&#xff0c;優化大語言模型預訓練流程&#xff0c;使大語言模型預訓練效率更高&#xff0c;訓練過程更穩定。 本文介紹深度學習領域…

利用EasyCVR平臺打造化工園區視頻+AI智能化監控管理系統

化工園區作為化工產業的重要聚集地&#xff0c;其安全問題一直是社會關注的焦點。傳統的人工監控方式效率低下且容易出現疏漏&#xff0c;已經難以滿足日益增長的安全管理需求。 基于EasyCVR視頻匯聚平臺構建的化工園區視頻AI智能化應用方案&#xff0c;能夠有效解決這些問題&…

GB28181視頻監控流媒體平臺LiveGBS如何自定義收流端口區間以便減少收流端口數或解決端口沖突問題

LiveGBS GB28181流媒體服務在接收視頻的時候默認是使用30000-30249&#xff0c; webrtc流播放端口區間默認是UDP的30250-30500區間。有些網絡環境不方便開放這么大的端口區間&#xff0c;下面介紹下如何修改配置這個區間。 從頁面上修改這個區間&#xff0c;端口區間盡量設置大…