一次數據庫性能優化測試,整理最全數據庫優化方案,還不快收藏

因爲配置是運行過那麼長時間,很穩定,基本上不考慮,因此本次主要是sql的優化,而且集中在業務的我的空間。下面是此次優化的數據庫版本:mysql

img

案例一:粉絲查詢優化git

粉絲查詢有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

優化思路數據庫

簡化sql,自帶的userid的邏輯放到代碼層去處理緩存

優化後tomcat

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秒多

img

優化思路

取私信表的最新的兩我的的對話放入一個新建的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.

好比下面這個:

img

緣由是mysql查詢只使用一個索引,若是where字句用了索引的話,那麼order by 中的列是不會使用索引的。因此order by的條件也須要添加到索引裏面組成聯合索引,優化後

img

還有一個須要注意的點是,索引有個最左前綴的原則:聯合索引(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佔用率立刻下來了

img

小結

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

 

寫在最後

通過此次優化,我的空間打開速度提高了,總結幾條心得:

1.不要期望全部SQL語句都能經過SQL優化,業務上的調整帶來意想不到的效果;

2.全部的性能優化都是空間換時間,經過冗餘來提升性能,大致思路都是大化小,分而治之

3.explain是sql優化的入門

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

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

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

就像以前寫過的tomcat的相關內容:Tomcat性能優化先後,有多大的差距,今天測試給你們看

以上不正之處請指出。


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

img

須要這份學習文檔的,關注+轉發後,私信「資料」便可查看獲取方式

而除了索引優化以外,對於數據庫的優化還有一些其餘的方面,就像汽車維修同樣,你只有瞭解它的內部構造,才能更好的對他進行維護,因此除了性能調優以外,你還須要瞭解數據庫的相關構造,才能更好的進行性能優化,爲你們推薦一本書,內容從架構到優化全涵蓋,相信會對你的學習產生幫助

目錄

img

架構

img

建立高性能索引

img

查詢性能優化

img

可擴展的mysql

img

應用層調優

img

應用工具

img

附錄

img

img

須要這份優化思惟導圖以及上面的知識圖的老鐵,添加小助手:msbxq2020免費獲取,同步的還有相關的視頻講解以及學習文檔,還不快點行動

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

部分資料已經上傳到個人git倉庫中:有須要的能夠下載

相關文章
相關標籤/搜索