只有當查詢優化,索引優化,庫表結構優化齊頭並進時,才能實現mysql高效能。
在嘗試編寫快速的查詢之前,需要清楚一點,真正重要是響應時間。
查詢的生命週期:
通常來說,查詢的生命週期大致可以按照順序來看:從客戶端->伺服器->然後再伺服器上進行解析->生成執行計畫->執行->並返回結果給客戶端。
其中"執行"可以認為是整個生命週期最重要的階段,這其中包括了大量為了檢索資料到儲存引擎的呼叫以及呼叫後的資料處理,包括排序,分組等。
對於乙個查詢的全部生命週期,上面列的並不完整。這裡我們只是想說:了解查詢的生命週期,清楚查詢的時間消耗情況對於優化查詢有很大的意義。
慢查詢基礎:優化資料訪問
1.是否向資料庫請求了不需要的資料
2.mysql是否掃瞄額外的紀錄
查詢是否掃瞄了過多的資料。最簡單的衡量查詢開銷三個指標如下:
響應時間。
掃瞄的行數。
返回的行數。
沒有哪個指標能夠完美地衡量查詢的開銷,但它們大致反映了mysql在內部執行查詢時需要多少資料,並可以推算出查詢執行的時間。
這三個指標都會記錄到mysql的慢日誌中,所以檢查慢日誌記錄是找出掃瞄行數過多的查詢的好辦法。
是兩個部分之和:服務時間和排隊時間。
服務時間是指資料庫處理這個查詢真正花了多長時間。
排隊時間是指伺服器因為等待某些資源而沒有真正執行查詢的時間。---可能是等io操作完成,也可能是等待行鎖,等等。
掃瞄的行數和返回的行數:
分析查詢時,檢視該查詢掃瞄的行數是非常有幫助的。這在一定程度上能夠說明該查詢找到需要的資料的效率高不高。
掃瞄的行數和訪問型別:
在expain語句中的type列反應了訪問型別。訪問型別有很多種,
從全表掃瞄(all)到
索引掃瞄(index)到
範圍掃瞄()到
唯一索引查詢 到
常數引用等。這裡列的這些,速度由慢到快,掃瞄的行數也是從小到大。
如果發現查詢需要掃瞄大量的資料但只返回少數的行,那麼通常可以嘗試下面的技巧去優化它:
使用索引覆蓋掃瞄。
改變庫表結構。例如使用單獨的彙總表。
重寫這個複雜的查詢。讓mysql優化器能夠以更優化的方式執行這個查詢。
一些簡單的重構查詢的方式:
1.乙個複雜查詢 or 多個簡單查詢
設計查詢的時候乙個需要考慮的重要問題是,是否需要將乙個複雜的查詢分成多個簡單的查詢。
2.切分查詢
有時候對於乙個大查詢我們需要「分而治之」,將大查詢切分為小查詢,每個查詢功能完全一樣,只完成一小部分,每次
只返回一小部分查詢結果。
3.分解關聯查詢
select * from tag
join tag_post on tag_post.tag_id = tag.id
join post on tag_post.post_id = post.id
where tag.tag = 'mysql'
可以分解成下面這些查詢來代替:
> select * from tag where tag = 'mysql'
> select * from tag_post where tag_id = 1234
> select * from post where post_id in (123, 456, 567, 9098, 8904)
優勢:讓快取的效率更高。
將查詢分解後,執行單個查詢可以減少鎖的競爭。
在應用層做關聯,可以更容易對資料庫進行拆分,更容易做到高效能和可擴充套件。
查詢本身效率也可能會有所提公升。
可以減少冗餘記錄的查詢,
更進一步,這樣做相當於在應用中實現了雜湊關聯,而不是使用mysql的巢狀迴圈關聯。
查詢主流程:
當希望mysql能夠以更高的效能執行查詢時,最好的辦法就是農清楚mysql是如何優化和查詢的。
一旦理解這一點,很多查詢優化工作實現上就是遵循一些原則讓優化器能夠按照預想的合理的方式執行。
1.客戶端傳送一條查詢給伺服器
2.伺服器先檢查查詢快取,如果命中了快取,則立刻返回儲存在快取中的結果,否則進入下一階段。
3.伺服器進行sql解析,預處理,再由優化器生成對應的執行計畫,
4.mysql根據優化器生成的執行計畫,呼叫儲存引擎的api來執行查詢。
5.將結果返回給客戶端。
mysql連線狀態:
對於乙個mysql連線,或者說乙個執行緒,任何時刻都有乙個狀態,該狀態表示了mysql正在做什麼,有很多方式能檢視當前
狀態,最簡單的是使用show full processlist
在乙個查詢的週期中,狀態可能會變化很多次,
這些狀態有:
sleep:
執行緒正在等待客戶端傳送新的請求。
query:
執行緒正在執行查詢或者正在將結果傳送給客戶端。
locked:
在mysql伺服器層,該執行緒正在等待表鎖。在儲存引擎級別實現的鎖,
行鎖的引擎也經常會出現。
analyzing and statistics:
執行緒正在收集儲存引擎的統計資訊,並生成查詢的執行計畫。
copying to tmp table [on disk]:
執行緒正在執行查詢,並且將結果集複製到乙個臨時表,
這種狀態一般要麼是在做 group by 操作,要麼是檔案排序操作,或者是union操作
如果這個狀態後面還有 on disk 標記,那表示mysql正在將乙個記憶體臨時表放到磁碟上。
sorting result:
執行緒正在對結果集進行排序
sending data:
這表示多種情況,執行緒可能在多個狀態之間傳送資料,或者在生成結果集,或者在客戶端傳送請求。
mysql效能優化簡書 mysql 效能優化
1 伺服器層面 引數配置優化 減少客戶端使用連線數 可考慮使用快取 2 架構層面 讀寫分離 分庫 分表 分片 3 業務sql層面 檢視慢查詢日誌 sql優化 show variables like slow query 預設關閉 檢視日誌路徑 show variables like long que...
mysql效能優化簡書 MySQL效能優化
1 合理的建立及使用索引,索引不宜過多,過多的索引會占用更多的空間,而且每次增 刪 改操作都會重建索引。2 合理的冗餘字段 盡量建一些大表,考慮資料庫的三正規化和業務設計的取捨 3 select語句中盡量不要使用 count 從表中讀取越多的資料,查詢會變得更慢,因為它會增加了磁碟操作時間和資料網路...
mysql 效能優化簡述
用 explain 分析sql語句。使用max 函式時,給max的字段加索引來優化 把子查詢優化為連表查詢,但要注意有重複資料 優化limit技巧 1.使用有索引的列或主鍵進行order by 2.記錄上一次返回的最大id用where id last max id 來過濾資料 關於索引欄位的優化 出...