mysql 查询语句执行顺序_MySQL 查询语句执行过程
MySQL 查詢語句執(zhí)行過程
Mysql分為server層和存儲引擎兩部分,或許可以再加一層連接層
連接層(器)
Mysql使用的是典型的C/S架構(gòu)。連接器通過典型的TCP握手完成連接。
需要注的是,
如果用戶名和密碼都正確,那么該連接所擁有的權(quán)限僅僅是連接成功建立時的所讀取到的權(quán)限
這就意味著:當連接已經(jīng)建立后,我們在對該用戶的權(quán)限進行修改,這些修改要直到該用戶再次建立連接時才會生效。
這聽起來是個不好的設(shè)計,因為一旦建立連接,管理員是無法臨時收回權(quán)限的。
索性,MySQL也想到了這一點,因此對于已經(jīng)連接的空閑連接,在一定時間后會自動斷開 --- 由參數(shù)wait_timeout控制,默認值是8小時。
我們可以使用
show processlist
查看已有連接是否處于空閑(Sleep)狀態(tài)
想要使用示例數(shù)據(jù)庫詳見此處
我想,應(yīng)該是為了用戶權(quán)限的“穩(wěn)定”才有了上面所謂的“不安全”的設(shè)計,因此使用DDL(GRANT)語句的時候要更加謹慎才行。
另外需要注意的是,
MySQL在執(zhí)行過程中臨時使用的內(nèi)存是管理在連接對象中的
這就意味著,當我們連接一次然后不斷通過該連接進行操作時(即使用長連接時),臨時內(nèi)存會不斷積累,直到連接斷開的時候才釋放。但當內(nèi)存占用過大,被系統(tǒng)殺掉(OOM --- Out of memory ),就會表現(xiàn)為MySQL異常關(guān)閉/重啟。
為了避免這種狀況我們可以使用兩種規(guī)避方式:
避免長連接,盡量使用短連接 --- 但建立連接其實是很耗時的
使用MySQL5.7或者更高版本,可以通過mysql_reset_connection來初始化連接 --- 即在不重建連接的情況下釋放臨時內(nèi)存(它是一個API方法,而不是直接在mysql shell中使用的命令,詳見)
server層
就根據(jù)各個層次的名字一樣,顧名思義,我們主要在在server層處理一條SQL語句,而這個過程在MySQL8.0版本后如下所示:
(連接器)>> 分析器 >> 優(yōu)化器 >> 執(zhí)行器
分析器就是對SQL字符串的拆分與辨析
優(yōu)化器就是“擇優(yōu)”,即
在表里有多個索引的時候選擇使用哪個索引、在多表關(guān)聯(lián)(join)的時候選擇速度最快的join方式,如在進行如下查詢時
select * from t1 join t2 using(Id) where t1.a=10 and t2.b=20;
優(yōu)化器就會幫助我們選擇是 “先選出t1.a=10的部分再關(guān)聯(lián)t2” 還是 “先選出t2.b=20的部分再關(guān)聯(lián)t1”
執(zhí)行器,
開始執(zhí)行 》 判斷有沒有相關(guān)權(quán)限 》使用表定義中的引擎 》 進行掃描執(zhí)行語句
在8.0之前的版本還有“查詢緩存”的機制,就是將查詢過的結(jié)果放在緩存中以期望下次再次執(zhí)行相同查詢時能快速返回結(jié)果。但...哪里有那么多相同的查詢呢,更過分的是這里的相同還要求表要沒有發(fā)生改變,且語句的大小寫都要相同。Are you serious ?于是棄之。
存儲引擎
MySQL存儲引擎負責存儲和提取,其架構(gòu)是插件式,支持(默認)InnoDB等多個存儲引擎。
搜索引擎是針對表的,在create table 時可以使用engine = xxx來使用指定內(nèi)存引擎。
讓MySQL為我們記錄執(zhí)行流程
總結(jié)
以上是生活随笔為你收集整理的mysql 查询语句执行顺序_MySQL 查询语句执行过程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 注册公司没有办公地点怎么办 解决办法其
- 下一篇: mysql设置catalog_catal