程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> 關於MYSQL數據庫 >> mysql sql語句優化的幾個原則和思路

mysql sql語句優化的幾個原則和思路

編輯:關於MYSQL數據庫

在分析如何優化 MySQL Query 之前,須要先了解一下 Query 語句優化的基本思路和原則。一般來說,Query 語句的優化思路和原則主要體現在以下幾個方面:

(1)優化更需要優化的Query;

(2)定位優化對象的性能瓶頸;

(3)明確優化目標;

(4)從 Explain 入手;

(5)多使用Profile;

(6)永遠用小結果集驅動大的結果集;

(7)盡可能在索引中完成排序;

(8)只取自己需要的Columns;

(9)僅僅使用最有效的過濾條件;

(10)盡可能避免復雜的Join和子查詢。

上面所列的幾點信息,前面4點可以理解為Query優化的一個基本思路,後面部分則是優化的基本原則。

下面先針對 Query 優化的基本思路做一些簡單的分析,理解Query優化到底該如何進行。

優化更須要優化的 Query

為什麼須要優化更須要優化的 Query?我想這個問題不需要過多的解釋。那什麼樣的 Query更須要優化呢?這個問題須要從對整個系統的影響來考慮。哪個Query 的優化能給系統整體帶來更大的收益,就更須要優化。一般來說,高並發低消耗(相對)的 Query 對整個系統的影響遠比低並發高消耗的大。下面可以通過以下一個非常簡單的案例分析充分說明問題。

假設有一個Query每小時執行10 000次,每次需要 20個IO,而另外一個Query每小時執行10次,每次需要20 000個IO。

首先通過IO消耗來分析。可以看出,兩個 Query 每小時所消耗的 IO總數目是一樣的,都是 200 000 IO/小時。假設優化第一個 Query,從20個IO降低到18個IO,也就是降低了 2 個IO,則節省了2×10 000 = 20 000 (IO/小時)。而如果希望通過優化第二個 Query達到相同的效果,必須要讓每個 Query 減少 20 000 / 10 = 2000 IO。可以看出第一個Query節省2個IO即可達到第二個 Query 節省2000個IO相同的效果。

其次,通過 CPU消耗來分析。原理和上面一樣,只要讓第一個 Query節省一小塊資源,就可以讓整個系統節省出一大塊資源,尤其是在排序、分組這些對 CPU 消耗比較多的操作中更加明顯。

最後,從對整個系統的影響來分析。一個頻繁執行的高並發 Query 的危險性比一個低並發的 Query要大很多。當一個低並發的 Query執行計劃有誤時,所帶來的影響只是該 Query請求者的體驗會變差,對整體系統的影響並不會特別突出,至少還屬於可控范圍。但是,如果一個高並發的 Query執行計劃有誤,那它帶來的後果很可能就是災難性的,很多時候可能連自救的機會都沒有,就會讓整個系統崩潰掉。我曾經就遇到過這樣一個案例,一個 並發度較高的Query語句執行計劃有誤,系統頃刻間崩潰,當重新啟動數據庫提供服務時,系統負載直線飙升,甚至都來不及登錄數據庫查看有哪些 Active 的線程在執行哪些 Query。如果是遇到一個並發不太高的 Query執行計劃有誤,至少還可以控制整個系統,不至於系統被直接壓跨,甚至連問題根源都難以抓到。

定位優化對象的性能瓶頸

當我們拿到一條須要優化的Query時,第一件事情是什麼?是反問自己這條 Query有什麼問題?我為什麼要優化他?只有明白了這些問題,才能知道須要做什麼,才能夠找到問題的關鍵。不能只是覺得某個 Query 好像有點慢,須要優化一下,然後就開始一個一個優化方法去輪番嘗試。這樣很可能會消耗大量的人力和時間成本,甚至可能到最後還是得不到一個好的優化結果。 這就像看病一樣,醫生必須要清楚病的根源才能對症下藥。如果只是知道什麼地方不舒服,然後就開始通過各種藥物嘗試治療,那後果可能就非常嚴重了。

所以,在拿到一條須要優化的 Query 之後,首先要判斷出這個 Query 的瓶頸到底是IO還是CPU,到底是因為在數據訪問上消耗了太多的時間,還是在數據的運算(如分組排序等)方面花費了太多資源。

一般來說,在MySQL 5.0系列版本中,可以通過系統自帶的 PROFILING功能清楚地找出一個 Query的瓶頸。當然,如果讀者朋友為了使用 MySQL 的某些在 5.1 版本中才有的新特性(如 Partition,EVENT等),抑或是早早使用MySQL 5.1 的預發布版本,可能就沒辦法使用這個功能了,因為該功能在MySQL 5.1 系列最初的版本中並不支持,不過讓人非常興奮的是該功能在最新的 MySQL 5.1 正式版(5.1.30)又已經提供了。如果讀者朋友正在使用的是4.x版本,那就只能通過自行分析 Query 的各個執行步驟,找到性能損失最大的地方了。

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