一條SQL語句執行得很慢的原因盤點

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"前言","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"說實話,這個問題可以涉及到 MySQL 的很多核心知識,可以扯出一大堆,就像要考你計算機網絡的知識時,問你“輸入URL回車之後,究竟發生了什麼”一樣,看看你能說出多少了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"所以一篇文章肯定是講不完的,我這篇文章,更多的是在分析“爲什麼”,例如可能你知道系統會選錯索引,但是可能不併不清楚系統選擇索引的原理。如果想搞清楚後者,可以點擊領取我整理的","attrs":{}},{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s?__biz=MzkzNjE1NTcyNQ==&mid=2247484482&idx=1&sn=00b0d901e54138676e93efba888cc037&chksm=c2a24b60f5d5c276b8d81c354293fd13413ef50e5425f1dda832f96a1dba5e3a2f19804a1d7e&token=1831800176&lang=zh_CN#rd","title":"","type":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"MySQL學習筆記","attrs":{}}]},{"type":"text","text":",我在裏面有詳細的論述。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"好了,說回正題!","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"之前騰訊面試的實話,也問到這個問題了,不過答的很不好,之前沒去想過相關原因,導致一時之間扯不出來。所以今天,我帶大家來詳細扯一下有哪些原因,相信你看完之後一定會有所收穫,不然你打我。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"開始裝逼:分類討論","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一條 SQL 語句執行的很慢,那是每次執行都很慢呢?還是大多數情況下是正常的,偶爾出現很慢呢?所以我覺得,我們還得分以下兩種情況來討論。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1、大多數情況是正常的,只是偶爾會出現很慢的情況。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2、在數據量不變的情況下,這條SQL語句一直以來都執行的很慢。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"針對這兩種情況,我們來分析下可能是哪些原因導致的。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"針對偶爾很慢的情況","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一條 SQL 大多數情況正常,偶爾才能出現很慢的情況,針對這種情況,我覺得這條SQL語句的書寫本身是沒什麼問題的,而是其他原因導致的,那會是什麼原因呢?","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"數據庫在刷新髒頁我也無奈啊","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當我們要往數據庫插入一條數據、或者要更新一條數據的時候,我們知道數據庫會在","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"內存","attrs":{}},{"type":"text","text":"中把對應字段的數據更新了,但是更新之後,這些更新的字段並不會馬上同步持久化到","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"磁盤","attrs":{}},{"type":"text","text":"中去,而是把這些更新的記錄寫入到 redo log 日記中去,等到空閒的時候,在通過 redo log 裏的日記把最新的數據同步到","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"磁盤","attrs":{}},{"type":"text","text":"中去。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不過,redo log 裏的容量是有限的,如果數據庫一直很忙,更新又很頻繁,這個時候 redo log 很快就會被寫滿了,這個時候就沒辦法等到空閒的時候再把數據同步到磁盤的,只能暫停其他操作,全身心來把數據同步到磁盤中去的,而這個時候,","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"就會導致我們平時正常的SQL語句突然執行的很慢","attrs":{}},{"type":"text","text":",所以說,數據庫在在同步數據到磁盤的時候,就有可能導致我們的SQL語句執行的很慢了。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"拿不到鎖我能怎麼辦","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這個就比較容易想到了,我們要執行的這條語句,剛好這條語句涉及到的","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"表","attrs":{}},{"type":"text","text":",別人在用,並且加鎖了,我們拿不到鎖,只能慢慢等待別人釋放鎖了。或者,表沒有加鎖,但要使用到的某個一行被加鎖了,這個時候,我也沒辦法啊。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果要判斷是否真的在等待鎖,我們可以用 ","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"show processlist","attrs":{}},{"type":"text","text":"這個命令來查看當前的狀態哦,這裏我要提醒一下,有些命令最好記錄一下,反正,我被問了好幾個命令,都不知道怎麼寫,呵呵。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下來我們來訪分析下第二種情況,我覺得第二種情況的分析纔是最重要的","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"針對一直都這麼慢的情況","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果在數據量一樣大的情況下,這條 SQL 語句每次都執行的這麼慢,那就就要好好考慮下你的 SQL 書寫了,下面我們來分析下哪些原因會導致我們的 SQL 語句執行的很不理想。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我們先來假設我們有一個表,表裏有下面兩個字段,分別是主鍵 id,和兩個普通字段 c 和 d。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"mysql> CREATE TABLE `t` (\n `id` int(11) NOT NULL,\n `c` int(11) DEFAULT NULL,\n `d` int(11) DEFAULT NULL,\n PRIMARY KEY (`id`)\n) ENGINE=InnoDB;\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"扎心了,沒用到索引","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"沒有用上索引,我覺得這個原因是很多人都能想到的,例如你要查詢這條語句","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"text"},"content":[{"type":"text","text":"select * from t where 100
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章