【問題現象】
使用sphinx支援倒排索引,但sphinx從mysql查詢源資料的時候,查詢的記錄數才幾萬條,但查詢的速度非常慢,大概要4~5分鐘左右
【處理過程】
1)explain
首先懷疑索引沒有建好,於是使用explain檢視查詢計畫,結果如下:
從explain的結果來看,整個語句的索引設計是沒有問題的,除了第乙個表因為業務需要進行整表掃瞄外,其它的表都是通過索引訪問
2)show processlist;
explain看不出問題,那到底慢在**呢?
於是想到了使用 show processlist檢視sql語句執行狀態,查詢結果如下:
發現很長一段時間,查詢都處在 「 sending data 」狀態
查詢一下「sending data」狀態的含義,原來這個狀態的名稱很具有誤導性,所謂的「sending data」並不是單純的傳送資料,而是包括「收集 + 傳送 資料」。
這裡的關鍵是為什麼要收集資料,原因在於: mysql使用「索引」完成查詢結束後,mysql得到了一堆的行id,如果有的列並不在索引中,mysql需要重新到「資料行」上將需要返回的資料讀取出來返回個客戶端。
3)show profile
為了進一步驗證查詢的時間分布,於是使用了show profile命令來檢視詳細的時間分布
首先開啟配置:set profiling=on;
執行完查詢後,使用show profiles檢視query id;
使用show profile for query query_id檢視詳細資訊;
結果如下:
從結果可以看出,sending data的狀態執行了216s
4)排查對比
經過以上步驟,已經確定查詢慢是因為大量的時間耗費在了sending data狀態上,結合sending data的定義,將目標聚焦在查詢語句的 返回列上面
經過一 一排查,最後定為到乙個description的列上,這個列的設計為:`description` varchar(8000) default null comment '遊戲描述',
於是採取了對比的方法,看看「 不返回 description的結果」如何。show profile的結果如下:
可以看出,不返回description的時候,查詢時間只需要15s,返回的時候,需要216s, 兩者相差15倍
【原理研究】
至此問題已經明確,但原理上我們還需要繼續**。
可以看到,平均一行大約1.5k,innodb每頁16k,除去一些資料結構空間和保留空間,大概1/10的行需要採用溢位儲存(即將資料存放在另外的頁中),一旦採用了這種方式儲存,返回資料的時候 本來是順序讀取的資料,就變成了隨機讀取 了,所以導致效能急劇下降。
【解決方法】
找到了問題的根本原因,解決方法也就不難了。有幾種方法:
1) 查詢時去掉description的查詢 ,但這受限於業務的實現,可能需要業務做較大調整
2) 增大innodb buffer pool ,但由於innodb buffer pool會根據查詢進行自動調整,因此如果gm_platform_info不是熱門表,作用也不是很明顯
3) 表結構優化 ,將descripion拆分到另外的表,這個改動較大,需要已有業務配合修改
mysql 慢查詢 MySQL慢查詢
一 簡介 開啟慢查詢日誌,可以讓mysql記錄下查詢超過指定時間的語句,通過定位分析效能的瓶頸,才能更好的優化資料庫系統的效能。二 引數說明 slow query log 慢查詢開啟狀態 slow query log file 慢查詢日誌存放的位置 這個目錄需要mysql的執行帳號的可寫許可權,一般...
mysql配置慢查詢 MYSQL慢查詢配置
mysql慢查詢配置 1.慢查詢有什麼用?它能記錄下所有執行超過long query time時間的sql語句,幫你找到執行慢的sql,方便我們對這些sql進行優化.2.如何開啟慢查詢?首先我們先檢視mysql伺服器的慢查詢狀態是否開啟.執行如下命令 我們可以看到當前log slow queries...
mysql 慢查詢 測試 MySQL慢查詢測試實踐
1.開啟慢查詢的目的 開啟慢查詢日誌,可以讓mysql記錄下查詢超過指定時間的語句,通過定位分析效能的瓶頸,才能更好的優化資料庫系統的效能。2.設定mysql慢查詢 方法一 全域性變數設定 臨時生效 將 slow query log 全域性變數設定為 on 狀態 mysql set global s...