拼多多面試問了資料庫基礎知識,今天分享出來

敖 丙發表於2020-02-06

點贊再看,養成習慣,微信搜尋【三太子敖丙】關注這個被微信官方推薦過的逗比,本文 GitHub https://github.com/JavaFamily 已收錄,有一線大廠面試常考點。

前言

我是個標題黨,所有文章的名字只是我的噱頭,我們應該有一顆謙遜的心,所以希望大家懷著空杯心態好好學,一起進步。

資料庫我想大家應該一點都不陌生吧,我想不管你寫啥的,資料庫就算沒用過也聽過了,是我們專案體系裡面不可或缺的一環。

問了一圈,身邊朋友公司要麼用自研,要麼就清一色的MySQL,所以想看Oracle的朋友可能要失望了,但是不影響你瞭解資料庫的通用知識。

正文

你知道MySQL的基本架構麼?你能在紙上給我大致畫出這個示意圖麼?

好的那我們按照順序瞭解下,聯結器是啥?

我們要進行查詢,第一步就是先去連結資料庫,那這個時候就是聯結器跟我們對接。

他負責跟客戶端建立連結、獲取許可權、維持和管理連線。

連結的時候會經過TCP握手,然後身份驗證,然後我們輸入使用者名稱密碼就好了。

驗證ok後,我們就連上了這個MySQL服務了,但是這個時候我們處於空閒狀態。

怎麼檢視空閒連線列表?

show processlist,下圖就是我在自己的資料庫表執行命令的結果,其中的Command列顯示為Sleep的這一行,就表示現在系統裡面有一個空閒連線。

這裡需要注意的是,我們資料庫的客戶端太久沒響應,聯結器就會自動斷開了,這個時間引數是wait_timeout控制住的,預設時長為8小時。

斷開後重連的時候會報錯,如果你想再繼續操作,你就需要重連了。

這個有個我看過的書本的案例:

一個在政府裡的朋友說,他們的系統很奇怪,每天早上都得重啟一下應用程式,否則就提示連線資料庫失敗,他們都不知道該怎麼辦。

我分析說,按照這個錯誤提示,應該就是連線時間過長了,斷開了連線。資料庫預設的超時時間是8小時,而你們平時六點下班,下班之後系統就沒有人用了,等到第二天早上九點甚至十點才上班,這中間的時間已經超過10個小時了,資料庫的連線肯定就會斷開了。

是的,就是超出了超時時間,然後寫程式碼的人也沒注意到這個細節,所以才會出現這個問題。

把超時時間改得長一點,問題就解決了。

這種引數其實我們平時不一定能接觸到,但是真的遇到問題的時候,知道每個引數的大概用法,不至於讓你變成無頭蒼蠅。

那除了重新連結,還有別的方式麼?因為建立連結還是比較麻煩的。

使用長連線。

但是這裡有個缺點,使用長連線之後,記憶體會飆得很快,我們知道MySQL在執行過程中臨時使用的記憶體是管理在連線物件裡面的。

只有在連結斷開的時候才能得到釋放,那如果一直使用長連線,那就會導致OOM(Out Of Memory),會導致MySQL重啟,在JVM裡面就會導致頻繁的Full GC。

那你會怎麼解決?

我一般會定期斷開長連線,使用一段時間後,或者程式裡面判斷執行過一個佔用記憶體比較大的查詢後就斷開連線,需要的時候重連就好了。

還有別的方法麼?你這種感覺不優雅呀小老弟。

執行比較大的一個查詢後,執行mysql_reset_connection可以重新初始化連線資源。這個過程相比上面一種會好點,不需要重連,但是會初始化連線的狀態。

你瞭解MySQL的查詢快取麼?

MySQL拿到一個查詢請求後,會先到查詢快取看看,之前是不是執行過這條語句。

大家是不是好奇同一條語句在MySQL執行兩次,第一次和後面的時間是不一樣的,後者明顯快一些,這就是因為快取的存在。

他跟Redis一樣,只要是你之前執行過的語句,都會在記憶體裡面用key-value形式儲存著。

查詢的時候就會拿著語句先去快取中查詢,如果能夠命中就返回快取的value,如果不命中就執行後面的階段。

但是我還是不喜歡用快取,因為快取弊大於利。

哦?此話怎講?

快取的失效很容易,只要對錶有任何的更新,這個表的所有查詢快取就會全部被清空,就會出現快取還沒使用,就直接被清空了,或者積累了很多快取準備用來著,但是一個更新打回原形。

這就導致查詢的命中率低的可怕,只有那種只查詢不更新的表適用快取,但是這樣的表往往很少存在,一般都是什麼配置表之類的。

那我們查詢的時候不想用快取一般都是怎麼操作的,或者是用快取又怎麼操作?

可以顯示呼叫,把query_cache_type設定成為DEMAND,這樣SQL預設不適用快取,想用快取就用SQL_CACHE。

有個小技巧就是,我們之前開發的時候,都會去庫裡看看sql執行時間,但是可能是有快取的,一般我們就在sql前面使用SQL_NO_CACHE就可以知道真正的查詢時間了。

 select SQL_NO_CACHE * from B

快取在MySQL8.0之後就取消了,所以大家現在應該不需要太關注這個問題,主要是我之前用的版本都不高,所以快取一直有,在《高效能MySQL》書中也看到了一些關於快取的介紹,就想起來給大家也提一下了。

快取查詢完了應該做啥呢?

在快取沒有命中的情況下,就開始執行語句了,你寫的語句有沒有語法錯誤,這是接下來MySQL比較關心的點。

那他會怎麼做呢?會先做詞法分析,你的語句有這麼多單詞、空格,MySQL就需要識別每個字串所代表的是什麼,是關鍵字,還是表名,還是列名等等。

然後就開始語法分析,根據詞法分析的結果,語法分析會判斷你sql的對錯,錯了會提醒你的,並且會提示你哪裡錯了。

分析沒錯之後就進入下一步,優化器

主要是優化什麼呢?

優化就比較簡單了,因為我們建立表可能會建立很多索引,優化有一步就是要確認使用哪個索引,比如使用你的主鍵索引,聯合索引還是什麼索引更好。

還有就是對執行順序進行優化,條件那麼多,先查哪個表,還是先關聯,會出現很多方案,最後由優化器決定選用哪種方案。

最後就是執行了,執行就交給執行器去做。

第一步可能就是許可權的判斷,其實這裡我不確定的一個點就是,我接觸的公司很多都是自研的線上查詢系統,我們是不能用Navicat直連線上庫,只能去網頁操作,那表的許可權是在MySQL層做的,還是系統做的,我猜應該是系統層做的,MySQL可能預設就全開放了,只是我們 不知道ip。

有知道的小夥伴也可以在公眾號【三太子敖丙】去加我微信跟我說。

執行的時候,就一行一行的去判斷是否滿足條件,有索引的執行起來可能就好點,一行行的判斷就像是介面都提前在引擎定義好了,所以他比較快。

資料庫的慢日誌有個rows_examined欄位,掃描多少行可以看到,還有explain也可以看到執行計劃,我們掃描了多少行。

可以小夥子,基礎大致框架還是瞭解得很清楚的,我們下次深入瞭解下,索引和部分機制。

好的,我們下次見。

總結

基本上我把MySQL的邏輯架構的東西都簡單聊了一遍,當然你去自信瞭解的話,你會發現其實裡面還有很多細節的,我只是說了一些常見的問題,這還是阿里丁奇學長的《MySQL實戰》的思路。

我自己在MySQL方面更多的可能就是理論知識了,還做不到深入瞭解的地步,大家如果有機會一定要深入的去學習一下。

絮叨

這應該是我開年的第一篇技術文,本來年前寫了一點索引的東西,但是後面在構思的時候想了想,還是從資料庫的基礎知識跟大家熟悉起來,再去了解索引會好點。

新年可能會嘗試一些新的文章風格,不一定全部用面試的方式,當然這篇是面試的風格,因為新的風格還沒決定。我還會嘗試著在4月份以後開始以視訊錄製這樣的方式嘗試幾期,大家有什麼意見也可以在微信上跟我說。

以後絮叨我也放最後,這樣大家閱讀體驗好點,反正有啥直接跟我反饋,寵粉的我,紛紛安排。

大家最近一定穿好衣服不要感冒啥的,雞蛋去看個病,差點嚇尿了,給你們看看他的裝備:

白嫖不好,創作不易,各位的點贊就是丙丙創作的最大動力,我們下篇文章見,文末圖片有福利

持續更新,未完待續……


文章每週持續更新,可以微信搜尋「 三太子敖丙 」第一時間閱讀,回覆【資料】【面試】有我準備的一線大廠面試資料和文章,本文 GitHub https://github.com/JavaFamily 已經收錄,有大廠面試完整考點,歡迎Star。

你知道的越多,你不知道的越多

相關文章