程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQL性能優化教程一(1)

MySQL性能優化教程一(1)

編輯:MySQL綜合教程

編者注:這是一篇MySQL性能優化的教程,來著某公司的DBA,原是為了培訓公司員工用,現在轉載出來供大家一起學習提高。

背景及目標

● 用於員工培訓和分享。

● 針對用戶群為已經使用過mysql環境,並有一定開發經驗的工程師

● 針對高並發,海量數據的互聯網環境。

● 本文語言為口語,非學術標准用語。

● 以實戰和解決具體問題為主要目標,非應試,非常規教育。友情提醒,在校生學習本教程可能對成績提高有害無益。

● 非技術挑戰,非高端架構師培訓,請高手自動忽略。

Mysql 執行優化

認識數據索引

1.為什麼使用數據索引能提高效率

■ 數據索引的存儲是有序的

■ 在有序的情況下,通過索引查詢一個數據是無需遍歷索引記錄的

■ 極端情況下,數據索引的查詢效率為二分法查詢效率,趨近於 log2(N)

2.如何理解數據索引的結構

■ 數據索引通常默認采用btree索引,內存表也使用了hash索引)。

■ 單一有序排序序列是查找效率最高的二分查找,或者說折半查找),使用樹形索引的目的是為了達到快速的更新和增刪操作。

■ 在極端情況下比如數據查詢需求量非常大,而數據更新需求極少,實時性要求不高,數據規模有限),直接使用單一排序序列,折半查找速度最快。

◆實戰范例 : ip地址反查

資源:

Ip地址對應表,源數據格式為  startip, endip, area

源數據條數為 10萬條左右,呈很大的分散性

目標: 

需要通過任意ip查詢該ip所屬地區

性能要求達到每秒1000次以上的查詢效率

挑戰:

如使用 between … and 數據庫操作,無法有效使用索引。

如果每次查詢請求需要遍歷10萬條記錄,根本不行。

方法: 

一次性排序只在數據准備中進行,數據可存儲在內存序列)

折半查找每次請求以折半查找方式進行)

■ 在進行索引分析和SQL優化時,可以將數據索引字段想象為單一有序序列,並以此作為分析的基礎。

◆實戰范例:復合索引查詢優化實戰,同城異性列表

資源: 用戶表user,字段 sex性別;area 地區;lastlogin 最後登錄時間;其他略

目標:

查找同一地區的異性,按照最後登錄時間逆序

高訪問量社區的高頻查詢,如何優化。

查詢SQL: select * from user where area=’$area’ and sex=’$sex’ order by lastlogin desc limit 0,30;

挑戰: 

建立復合索引並不難, area+sex+lastlogin 三個字段的復合索引,如何理解?

首先,忘掉btree,將索引字段理解為一個排序序列。

如果只使用area會怎樣?搜索會把符合area的結果全部找出來,然後在這裡面遍歷,選擇命中sex的並排序。 遍歷所有 area=’$area’數據!

如果使用了area+sex,略好,仍然要遍歷所有area=’$area’ and sex=’$sex’數據,然後在這個基礎上排序!!

Area+sex+lastlogin復合索引時切記lastlogin在最後),該索引基於area+sex+lastlogin 三個字段合並的結果排序,該列表可以想象如下。

廣州女$時間1

廣州女$時間2

廣州女$時間3

廣州男

….

深圳女

….
數據庫很容易命中到 area+sex的邊界,並且基於下邊界向上追溯30條記錄,搞定!在索引中迅速命中所有結果,無需二次遍歷!

3.如何理解影響結果集

■ 影響結果集是數據查詢優化的一個重要中間數據

◆ 查詢條件與索引的關系決定影響結果集

如上例所示,即便查詢用到了索引,但是如果查詢和排序目標不能直接在索引中命中,其可能帶來較多的影響結果。而這會直接影響到查詢效率

◆ 微秒級優化

● 優化查詢不能只看慢查詢日志,常規來說,0.01秒以上的查詢,都是不夠優化的。

● 實戰范例

和上案例類似,某游戲社區要顯示用戶動態,select * from userfeed where uid=$uid order by lastlogin desc limit 0,30;   初期默認以uid為索引字段, 查詢為命中所有uid=$uid的結果按照lastlogin排序。 當用戶行為非常頻繁時,該SQL索引命中影響結果集有數百乃至數千條記錄。查詢效率超過0.01秒,並發較大時數據庫壓力較大。

解決方案:將索引改為 uid+lastlogin 復合索引,索引直接命中影響結果集30條,查詢效率提高了10倍,平均在0.001秒,數據庫壓力驟降。

■ 影響結果集的常見誤區

◆ 影響結果集並不是說數據查詢出來的結果數或操作影響的結果數,而是查詢條件的索引所命中的結果數。

◆ 實戰范例

● 某游戲數據庫使用了innodb,innodb是行級鎖,理論上很少存在鎖表情況。出現了一個SQL語句(delete from tabname where xid=…),這個SQL非常用SQL,僅在特定情況下出現,每天出現頻繁度不高一天僅10次左右),數據表容量百萬級,但是這個xid未建立索引,於是悲慘的事情發生了,當執行這條delete 的時候,真正刪除的記錄非常少,也許一到兩條,也許一條都沒有;但是!由於這個xid未建立索引,delete操作時遍歷全表記錄,全表被delete操作鎖定,select操作全部被locked,由於百萬條記錄遍歷時間較長,期間大量select被阻塞,數據庫連接過多崩潰。

這種非高發請求,操作目標很少的SQL,因未使用索引,連帶導致整個數據庫的查詢阻塞,需要極大提高警覺。

■ 總結:

◆ 影響結果集是搜索條件索引命中的結果集,而非輸出和操作的結果集。

◆ 影響結果集越趨近於實際輸出或操作的目標結果集,索引效率越高。

◆ 請注意,我這裡永遠不會講關於外鍵和join的優化,因為在我們的體系裡,這是根本不允許的! 架構優化部分會解釋為什麼。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved