delete 後加 limit 是個好習慣麼

在業務場景要求高的數據庫中,對於單條刪除和更新操作,在 delete 和 update 後面加 limit 1 絕對是個好習慣。比如,在刪除執行中,第一條就命中了刪除行,如果 SQL 中有 limit 1;這時就 return 了,否則還會執行完全表掃描才 return。效率不言而喻。

那麼,在日常執行 delete 時,我們是否需要養成加 limit 的習慣呢?是不是一個好習慣呢?

在日常的 SQL 編寫中,你寫 delete 語句時是否用到過以下 SQL?

delete from t where sex = 1 limit 100;

你或許沒有用過,在一般場景下,我們對 delete 後是否需要加 limit 的問題很陌生,也不知有多大區別,今天帶你來了解一下,記得 mark!

寫在前面,如果是清空表數據建議直接用 truncate,效率上 truncate 遠高於 delete,應爲 truncate 不走事務,不會鎖表,也不會生產大量日誌寫入日誌文件;truncate table table_name 後立刻釋放磁盤空間,並重置 auto_increment 的值。delete 刪除不釋放磁盤空間,但後續 insert 會覆蓋在之前刪除的數據上。詳細瞭解請跳轉另一篇博文《delete、truncate、drop 的區別有哪些,該如何選擇》

下面只討論 delete 場景,首先,delete 後面是支持 limit 關鍵字的,但僅支持單個參數,也就是 [limit row_count],用於告知服務器在控制命令被返回到客戶端前被刪除的行的最大值。

delete limit 語法如下:

(值得注意的是,當需要用到 order by 排序時,必須 order by + limit 聯用,否則 order by 就會被優化器優化掉,被認爲無意義。)

delete [low_priority] [quick] [ignore] from tbl_name
  [where ...]
    [order by ...]
      [limit row_count]

加 limit 的的優點:

以下面的這條 SQL 爲例:

delete from t where sex = 1;

針對上述第二點,前提是 sex 上加了索引,大家都知道,加鎖都是基於索引的,如果 sex 字段沒索引,就會掃描到主鍵索引上,那麼就算 sex = 1 的只有一條記錄,也會鎖表。

對於 delete limit 的使用,MySQL 大佬丁奇有一道題:

如果你要刪除一個表裏面的前 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 是個值得養成的好習慣。

好了,本文就帶你瞭解這些,如果有相關疑問和好想法,請在下方留言,方便和小夥伴兒們一起討論。

一張照片背後的故事

這張照片拍攝於 2009 年
喜德縣北山鄉瓦伍村都來小學
一名女孩在上課時舉手回答問題
破爛的衣衫和教室
反而更能襯托出她眼神中對學習的渴望
有着這樣眼神的孩子
前方的路一定是充滿光明的

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://blog.csdn.net/qq_39390545/article/details/107519747