查詢語句的一套執行流程,更新語句也會同樣的走一步,下邊我們在對照上次文章中的圖來簡單的看一下:
" class="lazyload" src="https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d529960ec1dd496ca90860641bcaa093~tplv-k3u1fbpfcp-watermark.image" data- style="max-width:90%" data- style="max-width:90%">
首先,在執行語句前要先連接資料庫,這是第一步中連接器的工作,前面我們也說過,當一個表有更新的時候,跟這個表有關的查詢快取都會失效,所以我們通常不建議十月查詢快取。
接下來,分析器會經過語法分析和詞法分析,知道了這是一條更新語句後,優化器決定要使用哪一個索引,然後執行器負責具體的執行,先找到這一行,然後做更新。
與查詢語句更新不同的是,更新流程還涉及兩個重要的日誌,這個我們在前邊的文章中也有專門的介紹,有興趣的可以找一下上週的文章《MySQL的兩個日誌系統》,這裡就不多做介紹了。
下邊透過一個簡單的例子來分析一下更新操作的流程。
我們先建立一張表,這個表有主鍵ID和一個整數欄位c:
mysql> create table demo T (ID int primarty ,c int);复制代码
然後將ID=2的這一行的值加1
mysql> update table demo set c = c + 1 where ID = 2;复制代码
接下來我們來看看update語句的執行流程,圖中淺色框表示在儲存引擎中執行的,神色框代表的是執行器中執行的。
我們可以看到最後的時候,寫redolog的時候分了兩步,prepare和commit,這就是我們常說的「兩階段提交」。
為什麼日誌需要「兩階段提交」?
由於redo log和binlog分別是儲存引擎和執行器的日誌,是兩個獨立的邏輯,如果不用兩階段提交,無論先提交哪個後提交哪個都會存在一些問題。我們這裡也藉助上邊的例子看一下,假設當前ID=2的這一行值為0 ,在update的過程中寫完了第一個日誌後,第二個日誌還沒寫期間發生了crash,會怎麼樣?
我們可以看到如果不使用「兩階段提交",那麼資料庫的狀態就會和用日誌恢復出來的函式庫不一致。雖然平常用日誌恢復資料的機率比較低,但是用日誌最多的還是擴容的時候,用全量備份和binlog來實現的,這個時候就可能導致線上的主從資料庫不一致的情況。
#相關免費學習推薦:mysql影片教學
以上是SQL在MySQL資料庫中是如何執行的的詳細內容。更多資訊請關注PHP中文網其他相關文章!