1. 程式人生 > 實用技巧 >一次資料庫效能優化測試,整理最全資料庫優化方案,還不快收藏

一次資料庫效能優化測試,整理最全資料庫優化方案,還不快收藏

由於配置是執行過那麼長時間,很穩定,基本上不考慮,所以本次主要是sql的優化,並且集中在業務的個人空間。下面是這次優化的資料庫版本:

案例一:粉絲查詢優化

粉絲查詢有2條sql

--查詢所有粉絲
SELECT user FROM osc_friends f INNER JOIN osc_users u
ON u.id=f.user AND f.friend=? AND f.user<>? ORDER BY create_time DESC
--查詢粉絲數量
SELECT COUNT(friend) FROM osc_friends f INNER JOIN osc_users u
ON u.id=f.user AND f.friend = ? AND f.user <> ?

這兩個查詢在業務可以優化,inner join一個osc_users表目的是去掉osc_friends裡面自帶了自己的userid,偏偏osc_users表是比較大的表,為啥這樣設計,可以看看早年紅薯分享的OSChina 使用者動態設計說明

優化思路

簡化sql,自帶的userid的邏輯放到程式碼層去處理

優化後

SELECT user FROM osc_friends f WHERE f.friend=? ORDER BY create_time DESC

SELECT COUNT(*) FROM osc_friends f WHERE f.friend = ?

sql簡化了很多,大大提升了查詢速度

小結

有時候業務處理放到程式碼層,能達到意想不到的效果

案例二:私信優化

SELECT MAX(id) AS id, COUNT(id) AS msgCount 
FROM osc_msgs WHERE user = 12 GROUP BY friend ORDER BY id DESC

osc_msgs表儲存著所有的私信紀錄,隨著時間推移,該錶慢慢變大,一次查詢成本變高,基本都要1秒多

優化思路

取私信表的最新的兩個人的對話放入一個新建的osc_last_msgs表,每次發私信更新osc_last_msgs表,這個表只記錄最新的私信,這樣優化後的私信列表sql就不需要在msg表裡面找資料,只需要去osc_last_msgs表尋找.

優化後

SELECT * FROM osc_last_msgs WHERE user=? ORDER BY msg_id DESC

小結

把資料量從大化小的典型案例

案例三 評論優化

SELECT
l1.id
FROM
osc_opt_logs l1,
osc_opt_logs l2
WHERE
l1.obj_type IN (101, 111, 113, 116, 119, 121)
AND l2.obj_type IN (
100,
110,
112,
114,
118,
120,
123,
124,
122,
125,
126,
127,
99
)
AND l1.parent_id = l2.id
AND l2. USER = 12
ORDER BY
l1.id DESC
LIMIT 20;

嘗試建立聯合索引進行優化,不過效果不佳,因為optlog表特別的大,因此聯表查詢效率極低,佔用查詢快取空間極大。

優化思路

新增一個reply_user欄位,將回復的動彈進行標記,這樣子就可以簡化整個聯表查詢操作

優化後

SELECT id FROM osc_opt_logs where reply_user = 12 ORDER BY id DESC limit 20;

小結

適當的冗餘欄位可以降低sql的複雜度

案例四 索引優化

索引優化主要還是依賴explain命令,關於explain命令相信大家並不陌生,具體用法和欄位含義可以參考官網explain-output,這裡需要強調rows是核心指標,絕大部分rows小的語句執行一般很快。所以優化語句基本上都是在優化rows。

一般來說.

  • rows<1000,是在可接受的範圍內的。

  • rows在1000~1w之間,在密集訪問時可能導致效能問題,但如果不是太頻繁的訪問(頻率低於1分鐘一次),又難再優化的話,可以接受,但需要注意觀察

  • rows大於1萬時,應慎重考慮SQL的設計,優化SQL

這個沒有絕對值可參考,一般來說越小越好,,如果100萬資料量的資料庫,rows是70萬,通過這個可以判斷sql的查詢效能很差,如果100萬條資料量的資料庫,rows是1萬,從我個人的角度,還是能接受的。

另外就是extra的資訊,該列包含MySQL解決查詢的詳細資訊 ,重點關注出現關鍵字:

Using filesort:當Query 中包含order by 操作,而且無法利用索引完成排序操作的時候,MySQL Query Optimizer 不得不選擇相應的排序演算法來實現。

Using temporary:在某些操作中必須使用臨時表時,在 Extra 資訊中就會出現Using temporary ,主要常見於 GROUP BY 和 ORDER BY 等操作中

當執行計劃Extra 出現Using filesort 、Using temporary 時,可以考慮是否需要進行sql優化和調整索引,最後再調整my.cnf 中與排序或者臨時表相關的引數,如sort_buffer_size或者tmp_table_size.

比如下面這個:

原因是mysql查詢只使用一個索引,如果where字句用了索引的話,那麼order by 中的列是不會使用索引的。所以order by的條件也需要新增到索引裡面組成聯合索引,優化後

還有一個需要注意的點是,索引有個最左字首的原則:聯合索引(a,b,c)可以匹配(a)、(a,b)、(a,b,c)但不可以匹配(b,c)

小結

explain SQL語句應該是日常開發中的習慣動作,有時explain出來的結果,可能會出於偏離設計的意料之外

案例五 關注資料庫狀態

當滿滿期待優化後有大幅度效能提升的時候,現實總是跟你開玩笑,經過測試檢查,發現不是sql的問題,有可能是跟伺服器有關,用top命令看了發現mysql程序的cpu佔用率一直在100%左右,這就奇怪了,用show processlist看了一下mysql的程序,發現一個可疑的sql一直在執行,kill 掉後cpu佔用率馬上下來了

小結

當你發現數據庫cpu或者io有異常現象時候,用show processlist看看資料庫在忙什麼

寫在最後

經過這次優化,個人空間開啟速度提升了,總結幾條心得:

1.不要指望所有SQL語句都能通過SQL優化,業務上的調整帶來意想不到的效果;

2.所有的效能優化都是空間換時間,通過冗餘來提高效能,大體思路都是大化小,分而治之

3.explain是sql優化的入門

4.索引利大於弊,多用,善用之

如果再卡,可能會從分庫分表,讀寫分離這方面入手了。

優化前跟優化後的mysql是大大的不同,同樣用mysql,支撐起了淘寶,騰訊,facebook,但卻對你的業務系統支撐起來很吃力?

就像之前寫過的tomcat的相關內容:Tomcat效能優化前後,有多大的差距,今天測試給大家看

以上不正之處請指出。


對於我說的要多多使用的索引優化,相關的內容我通過一張思維導圖進行了整理和總結,其中包括如何操作,來看一下這張思維導圖

需要這份學習文件的,關注+轉發後,私信“資料”即可檢視獲取方式

而除了索引優化之外,對於資料庫的優化還有一些其他的方面,就像汽車維修一樣,你只有瞭解它的內部構造,才能更好的對他進行維護,所以除了效能調優之外,你還需要了解資料庫的相關構造,才能更好的進行效能優化,為大家推薦一本書,內容從架構到優化全涵蓋,相信會對你的學習產生幫助

目錄

架構

建立高效能索引

查詢效能優化

可擴充套件的mysql

應用層調優

應用工具

附錄

需要這份優化思維導圖以及上面的知識圖的老鐵,新增小助手:msbxq2020免費獲取,同步的還有相關的視訊講解以及學習文件,還不快點行動

關注公眾號:Java架構師聯盟,每日更新技術好文

部分資料已經上傳到我的git倉庫中:有需要的可以下載