1. 程式人生 > >【20180105】mysql日常優化一則

【20180105】mysql日常優化一則

ati 添加 http desc clas ima 不知道 gen 1.5

導讀:在日常的MySQL的SQL語句優化工作中,總會遇到了各種各樣的問題。今天就是遇到了一個比較詭異的問題,在這裏記錄下來方便自己的記憶。

MySQL版本信息: MySQL 5.6.38


  1. SQL語句(其中的關鍵字信息已經做脫敏處理):

SELECT id, name, headurl, intro, gender, location, job, birthday, source,created_at FROM user  WHERE name LIKE '%name%' ORDER BY created_at DESC LIMIT 0, 100;

2. 表user的表結構:

技術分享圖片

3. SQL的執行計劃和profile信息以及執行耗時:

技術分享圖片 4.優化思路:在執行計劃中可以看得到SQL語句由於是模糊查詢所以並沒有使用索引,並且在執行SQL之後可以明顯的看出在創建排序索引上面耗費了99%以上的時間,我們在看整個的SQL語句,只有在字段created_at上面有做排序操作,所以按照優化思路那麽我們就需要在created_at這個字段上面創建索引。創建索引之後的表結構:技術分享圖片

紅框就是添加的索引信息。

5.修改之後的SQL的執行計劃和profile以及耗時信息:

技術分享圖片

技術分享圖片

在上面的執行計劃進行比對我們可以很明顯的看出來,返回的數據由450w減少到了100行,數據量大大的減少了;但是在執行SQL之後發現耗時居然更長了使用了6s多,並且分析profile的時候發現在sending data耗時花費了6.6s的樣子,在這裏解釋一下 sending data耗時指的的是從引擎層發送數據到server層或者是client層。

發現這種情況我感到很吃驚,我並不知道發生了什麽事情導致這種結果。在多方查詢無果之後我之後請教我的一個師兄,經過我詳細的描述和實驗,他告訴我:主要是由於在where條件過濾和排序的時候走索引沒有查詢到任何的結果導致mysql獲取查詢所有的索引然後在去回表進行全局掃描;在沒有添加的索引的情況下,SQL直接就回回表不會進行全部的索引掃描。

為了驗證這個結果,我更改了where條件,在沒有添加created_at這個字段索引的情況下進行對比情況:

沒有添加索引的耗時:

100 rows in set (2.53 sec)

添加索引的耗時:

100 rows in set (0.16 sec)

可以很明顯的看到添加索引之後 速度提高了一大堆,並且這個是有查詢結果的。

【20180105】mysql日常優化一則