mysql 关联查询_响应时间长?MySQL查询优化教程来了!
為什么查詢會慢?——響應(yīng)時間過長。
如果把查詢看做是一個任務(wù),那么它由一系列子任務(wù)組成,每個子任務(wù)都會消耗一定的時間。如果要優(yōu)化查詢,實際上優(yōu)化其子任務(wù),要么消除其中一些子任務(wù),要么減少子任務(wù)的執(zhí)行次數(shù),要么讓子任務(wù)運行得更快。
查詢的生命周期:客戶端->服務(wù)器->服務(wù)器上解析->生成執(zhí)行計劃->執(zhí)行->返回結(jié)果給客戶端其中”執(zhí)行”包括大量為了檢索數(shù)據(jù)到存儲引擎的調(diào)用以及調(diào)用后的數(shù)據(jù)處理,包括排序、分組等。查詢性能低下最基本的原因:訪問的數(shù)據(jù)太多。低效查詢分析:確認(rèn)應(yīng)用程序是否在檢索大量超過需要的數(shù)據(jù)
確認(rèn)MySQL服務(wù)器層是否在分析大量超過需要的數(shù)據(jù)行
是否向數(shù)據(jù)庫請求了不需要的數(shù)據(jù)
典型案例(主要體現(xiàn)為了省事,使用SELECT *):查詢不需要的記錄
多表關(guān)聯(lián)時返回全部列
總是取出全部列
重復(fù)查詢相同數(shù)據(jù)
MySQL是否在掃描額外的記錄
在確定查詢只返回需要的數(shù)據(jù)以后,接下來看查詢?yōu)榱朔祷亟Y(jié)果是否掃描過多的數(shù)據(jù)。對于MySQL,最簡單的衡量查詢開銷的三個指標(biāo):1. 響應(yīng)時間響應(yīng)時間包含服務(wù)時間和排隊時間。服務(wù)時間是指數(shù)據(jù)庫處理這個查詢真正花了多長時間
排隊時間是指服務(wù)器因為等待某些資源而沒有真正執(zhí)行查詢的時間,可能等I/O操作完成,也可能等待行鎖
在索引中使用WHERE條件來過濾不匹配的記錄。這是存儲引擎層完成的。
使用索引覆蓋掃描(在Extra列中出現(xiàn)了Using index)來返回記錄,直接從索引中過濾不需要的記錄并返回命中的結(jié)果。這是在MySQL服務(wù)器層完成的,但無須再回表查詢記錄。
從數(shù)據(jù)表中返回數(shù)據(jù),然后過濾不滿足條件的記錄(在Extra列中出現(xiàn)Using Where)。這在MySQL服務(wù)器層完成,MySQL需要先從數(shù)據(jù)表讀出記錄然后過濾。
使用索引覆蓋掃描,把所有需要用的列都放在索引中,這樣存儲引擎無須回表獲取對應(yīng)行就可以返回結(jié)果了。
改變庫表結(jié)構(gòu)。例如使用單獨的匯總表。
重寫這個復(fù)雜查詢,讓MySQL優(yōu)化器能夠以更優(yōu)化的方式執(zhí)行這個查詢。
重構(gòu)查詢的方式
復(fù)雜查詢拆分多個簡單查詢。1. 切分查詢將大查詢拆分為小查詢,每個查詢功能完全一樣,只完成一小部分,每次只返回一小部分查詢結(jié)果。2. 分解關(guān)聯(lián)查詢用分解關(guān)聯(lián)查詢的方式重構(gòu)查詢有如下優(yōu)勢:讓緩存效率更高
將查詢分解后,執(zhí)行單個查詢可以減少鎖的競爭
在應(yīng)用層做關(guān)聯(lián),可以更容易對數(shù)據(jù)庫進行拆分,更容易做到高性能和可擴展
查詢本身效率也可能會有所提升
可以減少冗余記錄的查詢
相當(dāng)于在應(yīng)用中實現(xiàn)了哈希關(guān)聯(lián),而不是使用MySQL的嵌套循環(huán)關(guān)聯(lián)
客戶端發(fā)送一條查詢給服務(wù)器
服務(wù)器先檢查查詢緩存,如果命中緩存,則立刻返回存儲在緩存中的結(jié)果。否則進入下一階段
服務(wù)器端進行SQL解析、預(yù)處理,再由優(yōu)化器生成對應(yīng)的執(zhí)行計劃
MySQL根據(jù)優(yōu)化器生成的執(zhí)行計劃,調(diào)用存儲引擎的API來執(zhí)行查詢
將結(jié)果返回給客戶端
優(yōu)化特定類型的查詢
1. 優(yōu)化COUNT()查詢2. 優(yōu)化關(guān)聯(lián)查詢確保ON或USING子句中的列上有索引。
確保任何GROUP BY和ORDER BY 中的表達(dá)式只涉及到一個表中的列,這樣MySQL才有可能使用索引來優(yōu)化這個過程。
當(dāng)升級MySQL的時候需要注意:關(guān)聯(lián)語法、運算符優(yōu)先級等其他可能會發(fā)生變化的地方。因為以前是普通關(guān)聯(lián)的地方可能會變成笛卡爾積,不同類型的關(guān)聯(lián)可能會生成不同的結(jié)果等。
使用自定義變量的查詢,無法使用查詢緩存
不能再使用常量或者標(biāo)識符的地方使用自定義變量,例如表名、列名和LIMIT子句中
用戶自定義變量的生命周期是在一個連接中有效,所以不能用它們來做連接間的通信
如果使用連接池或者持久化連接,自定義變量可能讓看起來毫無關(guān)系的代碼發(fā)生交互
在5.0之前的版本,是大小寫敏感的,所以要注意代碼在不同MySQL版本間的兼容性問題
不能顯式地聲明自定義變量的類型。確定未定義變量的具體類型的時機在不同MySQL版本中也可能不一樣。如果你希望變量是整數(shù)類型,那么最好在初始化的時候就賦值為0,如果希望是浮點型則賦值為0.0,如果希望是字符串則賦值為’’,用戶自定義變量的類型在賦值的時候會改變。MySQL的用戶自定義變量是一個動態(tài)類型
MySQL優(yōu)化器在某項些場景下可能會將這些變量優(yōu)化掉,這可能導(dǎo)致代碼不按預(yù)想的方式運行
賦值的順序和賦值的時間點并不總是固定的,這依賴于優(yōu)化器的決定,實際情況可能很讓人困惑,后面我們將看到這一點
賦值符號:=的優(yōu)先級非常低,所以需要注意,賦值表達(dá)式應(yīng)該使用明確的括號
使用未定義變量不會產(chǎn)生任何語法錯誤,如果沒有意識到這一點,非常容易犯錯
查詢運行時計算總數(shù)和平均值
模擬GROUP BY語句中的函數(shù)FIRST()和LAST()
對大量數(shù)據(jù)做一些數(shù)據(jù)計算
計算一個大表的MD5散列值
編寫一個樣本處理函數(shù),當(dāng)樣本中的數(shù)值超過某個邊界值的時候?qū)⑵渥優(yōu)?
模擬讀/寫游標(biāo)
在SHOW語句的WHERE子句中加入變量值
球分享
球點贊
球在看
總結(jié)
以上是生活随笔為你收集整理的mysql 关联查询_响应时间长?MySQL查询优化教程来了!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 内存频率和时序:选择内存条的正确姿势
- 下一篇: linux cmake编译源码,linu