一條sql的執(zhí)行流程

image.png
- 客戶端連接Mysql,連接器負(fù)責(zé)連接管理和權(quán)限認(rèn)證。
- 連接之后會(huì)將查詢緩存中,如果緩存命中了,再檢查時(shí)候有訪問的權(quán)限,如果有,則返回?cái)?shù)據(jù)集,否則執(zhí)行3。
- 分析器負(fù)責(zé)對sql語句先解析語句,再檢查語句是否正確,交于優(yōu)化器。
- 優(yōu)化器負(fù)責(zé)索引的選擇和多表連接時(shí)選擇查詢順序,之后交于執(zhí)行器。
- 執(zhí)行器首先判斷時(shí)候有權(quán)限訪問表,如果有的話執(zhí)行器就根據(jù)表的定義的引擎去調(diào)用引擎接口,再接收數(shù)據(jù)集。
- 返回?cái)?shù)據(jù)集給客戶端。
查詢緩存好嗎?
查詢緩存中的好嗎?是不是要開啟查詢緩存呢?其實(shí)不建議開啟查詢緩存,原因是緩存失效非常頻繁,只要表更新了,緩存就會(huì)失效。所以對于那些更新操作多的表來說簡直是災(zāi)難,除非是靜態(tài)表,所以在mysql8中已經(jīng)將查詢緩存取消了。
Mysql中的長鏈接和短連接,長連接會(huì)導(dǎo)致什么問題?
- 長連接是指,當(dāng)客戶端連接數(shù)據(jù)庫之后,如果持續(xù)訪問數(shù)據(jù)庫,將保持連接。
- 短連接是指,當(dāng)客戶端連接數(shù)據(jù)庫之后,在很少的幾次操作之后就會(huì)斷開連接。
那是不是長連接就一定好呢?其實(shí)不是的,在長連接中,會(huì)產(chǎn)生大量的內(nèi)存使用,這些內(nèi)存會(huì)保存在連接對象中,所以長連接會(huì)導(dǎo)致內(nèi)存漲的很快,會(huì)到值OOM,表現(xiàn)的就是mysql異常重啟,那怎么解決呢?我們可以適時(shí)地將長連接斷開,這樣內(nèi)存就可以回收了,還有一個(gè)辦法就是重置連接對象,利用mysql_reset_connection命令,這樣就不用重連數(shù)據(jù)庫了,只是恢復(fù)連接對象到剛連接的狀態(tài)。
為什么查詢權(quán)限要在執(zhí)行階段?
這是因?yàn)閟ql操作涉及的表不一定只有sql語句中的那些,要在執(zhí)行器階段才能確認(rèn)。
問題:
如果表 T 中沒有字段 k,而你執(zhí)行了這個(gè)語句 select * from T
where k=1, 那肯定是會(huì)報(bào)“不存在這個(gè)列”的錯(cuò)誤: “Unknown column ‘k’ in
‘where clause’”。你覺得這個(gè)錯(cuò)誤是在我們上面提到的哪個(gè)階段報(bào)出來的呢?
答:分析器階段,在分析器階段解析器會(huì)解析sql語句生成一顆解析樹,判斷表時(shí)候存在,列字段是否存在等。