經過了幾天的記錄,系統中會多出了一個好幾 MB 的檔案,檔案內容就是大量的 MySQL 語法,執行時間等數據。
那不是給人看的,我們還是要將檔案整理成方便閱讀的格式。
slow-log 檔案 = log-slow-queries.log
要輸出的檔案 = slow.log
mysqldumpslow ./log-slow-queries.log > ./slow.log
這樣子就會得到一份經過處理的龜速 query 列表了。 以下為一個範例。
Count: 9 Time=0.29s (2s) Lock=0.00s (0s) Rows=1.0 (9), cyberlar[cyberlar]@localhost
SELECT post_modified_gmt FROM wp_posts WHERE post_status = ‘S’ ORDER BY post_modified_gmt DESC LIMIT N
其中 Count: 9 代表這段語法在這段期間共被執行了 9 次。
Time = 0.29s (2s) 代表平均每次執行 0.29 秒,這九次共花費了2秒的時間。
Lock = 0.00 代表語法在執行時將 table lock 起來不讓別的 query 使用的時間。
Rows=1.0 代表這語法平均每次執行後所輸出的資料筆數。
接下來的就是 SQL 語法了。 mysqldumpslow 會將字串以 S 代替,數字以 N 代替。
從這些資訊中我們就可以看出為什麼會慢了。
從範例中我們可以確定語法本身是沒問題的,因為這是很常見的查尋語法了。
且執行時間也才 0.29秒,那為什麼還是會被 log 下來呢?
因為當初我在設定時有讓 MySQL 同時將沒有使用到 index 的查尋也都 log 起來。
也許您會覺得這 0.3 秒的時間根本查覺不出來。 但是如果一個頁面必須要經過 10 中不同的 query 來抓取資料的話!
那麼要 load 這一頁,使用者就必須等待 3 秒。 每一頁都等3秒,等幾秒。 這種差別是很大的。
我在一個擁有 177849 筆資料的資料庫中做一個搜尋的動作,在被搜尋的資料表還沒加入 index 前,要找尋資料的速度為 0.1635 秒。 將該資料表加入 index 後搜尋的時間進步為0.0036 秒。 這種效能的進步是感覺的出來且有根據的。
另外,有許多語法寫的並不是很好的比方說 select 裡面還包了個 select。 這一類的語法一般最少都會要執行個 0.5 秒 1 秒的,就要更改程式對 mysql 做查尋時的方式來增加效能。
雖然將經常要做查尋或比對 join 的資料表做 index 會增加效能,但是一眛的亂加是會產生反效果的,除了會浪費過多的記憶體資源,當資料在做 update 時還會造成 index 重讀,讓效能變的更差。