讓你薪資翻倍的mysql優化面試回答,面試官都驚呆了。。

當面試官問你mysql優化

首先要知道mysql分爲兩個層次。你要逐一從各個層次講解mysql優化,讓面試官知道,哇,原來你對mysql這麼瞭解。

面試官:你知道哪些mysql優化?

我: …巴拉巴拉巴拉。

mysql結構層次

首先,mysql分爲server層和引擎層。

server層有連接器。對於連接器可以通過建立連接池來進行優化。連接器進行連接的時候會消耗資源,還會進行權限驗證等操作,爲了避免頻繁創建連接,所以使用連接池。

server層還有緩存模塊,只不過緩存模塊在新版本,也就是mysql8中被去掉了。

server層還有分析器,進行語法分析之類的,這裏沒啥可優化的。

server層還有優化器,優化器會對sql語句進行優化,以及選擇索引等操作。針對這裏的優化就是寫出更好的sql語句,儘量減少優化器的工作,用對索引,創建更好的索引等。具體的後面在詳細說明。

server層還有執行器,負責執行優化器輸出的執行計劃,執行計劃可以通過explain語句來查看,通過執行計劃可以看到執行掃描的行數,是否使用索引,在連表時候使用的算法,是否用到了排序等等信息。

除了server層就是引擎層的優化。引擎層的優化主要是通過優化sql語句和創建索引來完成。重點也就是sql語句和索引部分。

sql語句的優化

select * 還是字段問題

很多人都會說要使用select 字段而不是select *,那麼這到底爲什麼呢?真的慢嗎?慢在哪裏?

select * 的問題,拿innoDB引擎來說,其實innoDB中,不管是select * 還是字段,他的速度都差不多,因爲所有的數據都存放在主鍵索引中,主鍵索引是一個聚簇索引,主鍵id和數據放在一起,所以它拿的時候,都可以拿到所有字段。但是還是推薦需要哪個去哪個字段,這是因爲雖然都可以拿到,但是拿的東西許多,要傳輸的數據也就越多,而這會造成更大的網絡開銷,耗費網絡io資源,如果你的網絡不在乎這些,那麼其實速度上差不多

count (*)問題

count語句用於求數量,這個在後臺中用的尤其多。關於這個問題,到底是count()好還是count(id)好呢?有的人覺得id更好,因爲走了主鍵索引。其實不是,更好的是count(*)。因爲mysql團隊對count()這個語句進行了優化。具體怎麼優化的,因爲篇幅關係還請參考我的另一篇文章。所以千萬不要在寫什麼count(id)了,請直接使用count(*)吧。

不過這個主要是innoDB引擎,因爲Myisam引擎的總數量是有記錄的,所以不需要全表掃描,這也是兩個引擎的不同處。不過Myisam引擎在進行where條件的count時候還是需要全表掃描的。

innoDB引擎count的執行原理如果感興趣可以參考我這個文章。

join連表問題

很多時候都要進行join連表操作,有的人覺得連表很慢,還不如自己查詢兩次來的快。其實並不是,如果滿足以下幾點,那麼連表的速度是最優的:

  • 小表驅動大表,也就是數據量小的表作爲主表進行連接

  • 連表條件增加索引
    這樣的話其實連表是最快的,主要是因爲連表條件會走索引。
    如果連表條件沒有索引,那麼抱歉,速度真的很慢,他會對兩個表全都全表掃描。。。
    mysql innoDB join的執行原理,有興趣的可以參考我這個文章。

  • 爲什麼很多人不推薦mysql連表join查詢

查詢單條記錄問題

如果你只需要查詢一條記錄,那麼加上limit 1會更快。這是爲什麼呢?因爲innoDB再查詢到你需要的數據後會繼續往後查詢,直到查詢到不滿足條件爲止,所以如果你這麼寫:

select * from sys where user = 1;

如果user有索引,那麼會從索引上找到user = 1的記錄,然後從索引這個位置接着往下找,找到user = 2發現不滿足條件,然後回表查詢,返回數據。但是你要是加上limit 1

select * from sys where user = 1 limit 1;

這時候找到user = 1的記錄就不會再往下找了,所以速度會更快。

不過唯一索引沒有這個問題,因爲唯一索引是唯一的。

覆蓋索引問題

使用覆蓋索引可以避免innoDB引擎回表查詢,這樣速度也會提升,什麼是回表呢?就是當從其他索引上查詢到數據後,其他索引上只能查到主鍵id,還需要再走一遍主鍵索引,從主鍵索引上取數據。如果你的普通索引上通過建立聯合索引,來把數據放進去,就不需要回表了。

order by排序字段建立索引

給排序字段建立索引是因爲索引是有序的,不需要排序,這樣的話排序時候直接走有序索引就避免了排序過程。不然mysql還要進行以下排序。這樣就可以把排序的時間省掉。

order by 的具體執行原理可以參考我下面的文章:

where 字段建立索引

對於常用的where字段可以建立索引,多個where字段可以建立聯合索引。對於不怎麼常用的查詢,我們就沒必要建立索引了,畢竟索引建多了並不好,維護索引也是有代價的。

慢查詢日誌

一定要打開慢查詢日誌,如果發現慢查詢需要進行sql優化了。

避免長事務

不要寫長事務,不要把不必要的查詢操作納入事務中。

mysql函數問題

不要再查詢中使用mysql的函數,因爲使用函數會導致不走索引。

mysql類型轉換問題

不要再查詢中讓mysql進行類型轉換,比如

select * from user where mobile = 123.........

因爲mysql進行類型轉換會使用到函數,而用到函數會導致不走索引。

多看執行計劃

通過explain查詢執行計劃,看有沒有用到索引,mysql有時候會選錯索引,因爲是否走索引是通過抽樣調查來決定的,所以並不準確,再加上要回表查詢。所以有時候會不走索引。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章