在業務場景要求高的資料庫中,對於單條刪除和更新操作,在 delete 和 update 後面加 limit 1 絕對是個好習慣。比如,在刪除執行中,第一條就命中了刪除行,如果 sql 中有 limit 1;這時就 return 了,否則還會執行完全表掃瞄才 return。效率不言而喻。
那麼,在日常執行 delete 時,我們是否需要養成加 limit 的習慣呢?是不是乙個好習慣呢?
在日常的 sql 編寫中,你寫 delete 語句時是否用到過以下 sql?
delete from t where *** = 1 limit 100;
你或許沒有用過,在一般場景下,我們對 delete 後是否需要加 limit 的問題很陌生,也不知有多大區別,今天帶你來了解一下,記得 mark!
寫在前面,如果是清空表資料建議直接用 truncate,效率上 truncate 遠高於 delete,因為 truncate 不走事務,不會鎖表,也不會生產大量日誌寫入日誌檔案;truncate table table_name 後立刻釋放磁碟空間,並重置 auto_increment 的值。delete 刪除不釋放磁碟空間,但後續 insert 會覆蓋在之前刪除的資料上。下面只討論 delete 場景,首先,delete 後面是支援 limit 關鍵字的,但僅支援單個引數,也就是 [limit row_count],用於告知伺服器在控制命令被返回到客戶端前被刪除的行的最大值。
delete limit 語法如下,值得注意的是,order by 必須要和 limit 聯用,否則就會被優化掉。
delete \[low\_priority\] \[quick\] \[ignore\] from tbl\_name
\[where ...\]
\[order by ...\]
\[limit row\_count\]
以下面的這條 sql 為例:
delete from t where *** = 1;
針對上述第二點,前提是 *** 上加了索引,大家都知道,加鎖都是基於索引的,如果 *** 欄位沒索引,就會掃瞄到主鍵索引上,那麼就算 *** = 1 的只有一條記錄,也會鎖表。
請看下面這道題:
如果你要刪除乙個表裡面的前 10000 行資料,有以下三種方法可以做到:你先考慮一下,再看看幾位老鐵的回答:第一種,直接執行 delete from t limit 10000;
第二種,在乙個連線中迴圈執行 20 次 delete from t limit 500;
第三種,在 20 個連線中同時執行 delete from t limit 500。
回答一:
--------------------------------------------
回答二:
不考慮資料表的訪問併發量,單純從這個三個方案來對比的話。
至於選哪一種方案要結合實際場景,綜合考慮各個因素吧,比如表的大小,併發量,業務對此表的依賴程度等。
-------------------------------------------
回答三:
怎麼刪除表的前 10000 行。比較多的朋友都選擇了第二種方式,即:在乙個連線中迴圈執行 20 次 delete from t limit 500。確實是這樣的,第二種方式是相對較好的。
第一種方式(即:直接執行 delete from t limit 10000)裡面,單個語句占用時間長,鎖的時間也比較長;而且大事務還會導致主從延遲。
第三種方式(即:在 20 個連線中同時執行 delete from t limit 500),會人為造成鎖衝突。
這個例子對我們實踐的指導意義就是,在刪除資料的時候盡量加 limit。這樣不僅可以控制刪除資料的條數,讓操作更安全,還可以減小加鎖的範圍。所以,在 delete 後加 limit 是個值得養成的好習慣。
5年後 10年後,你希望自己是個什麼樣的人?
5 年後 10 年後,你想成為什麼樣的自己?你認真思考過這個問題嗎?可能你思考過這個問題,但一直沒有給自己乙個明確的答案,也可能你從來沒想過這個問題。這都很正常,畢竟我們都太容易陷入一日復一日的漩渦裡。每天早上起來乘一樣的交通工具行一樣的路去工作,做一樣的事情 下班行一樣的路回家,做一樣的事情 閒暇...
酒濃碼濃 訪問位址後電腦是怎麼解析成乙個頁面的
瀏覽器的位址列輸入 之後會發生什麼?首先我們要知道原始的位址都是ip格式的,純數字不便記憶 所以有了網域名稱,網域名稱解析了ip位址,所以你訪問乙個網域名稱其實訪問的是ip位址。進入網域名稱後,瀏覽器會進行dns解析網域名稱為ip,通過網路運維商或者快取資訊來找到目標伺服器 簡單的理解為伺服器就是乙...
在可以最多刪除乙個字元後判斷是回文串
給定乙個字串,在最多可以刪除乙個字元的條件下,判斷刪除後的剩下的是否為回文串。e.g 輸入輸出 aba或b abda aba 或 adaaa abcfalse include includeusing namespace std string ishuiwen string s for int i ...