delete后加 limit是個好習慣么?
點擊關注上方“SQL數(shù)據(jù)庫開發(fā)”,
設為“置頂或星標”,第一時間送達干貨
delete from t where sex = 1 limit 100;?
寫在前面,如果是清空表數(shù)據(jù)建議直接用 truncate,效率上 truncate 遠高于 delete,應為 truncate 不走事務,不會鎖表,也不會生產(chǎn)大量日志寫入日志文件;truncate table table_name 后立刻釋放磁盤空間,并重置 auto_increment 的值。delete 刪除不釋放磁盤空間,但后續(xù) insert 會覆蓋在之前刪除的數(shù)據(jù)上。詳細了解請?zhí)D另一篇博文《delete、truncate、drop 的區(qū)別有哪些,該如何選擇》
delete \[low\_priority\] \[quick\] \[ignore\] from tbl\_name
\[where ...\]
\[order by ...\]
\[limit row\_count\]
加 limit 的的優(yōu)點:
delete from t where sex = 1;?
1. 降低寫錯 SQL 的代價,就算刪錯了,比如 limit 500, 那也就丟了 500 條數(shù)據(jù),并不致命,通過 binlog 也可以很快恢復數(shù)據(jù)。 2. 避免了長事務,delete 執(zhí)行時 MySQL 會將所有涉及的行加寫鎖和 Gap 鎖(間隙鎖),所有 DML 語句執(zhí)行相關行會被鎖住,如果刪除數(shù)量大,會直接影響相關業(yè)務無法使用。 3. delete 數(shù)據(jù)量大時,不加 limit 容易把 cpu 打滿,導致越刪越慢。
如果你要刪除一個表里面的前 10000 行數(shù)據(jù),有以下三種方法可以做到:
第一種,直接執(zhí)行 delete from T limit 10000;
第二種,在一個連接中循環(huán)執(zhí)行 20 次 delete from T limit 500;
第三種,在 20 個連接中同時執(zhí)行 delete from T limit 500。
方案一,事務相對較長,則占用鎖的時間較長,會導致其他客戶端等待資源時間較長。 方案二,串行化執(zhí)行,將相對長的事務分成多次相對短的事務,則每次事務占用鎖的時間相對較短,其他客戶端在等待相應資源的時間也較短。這樣的操作,同時也意味著將資源分片使用(每次執(zhí)行使用不同片段的資源),可以提高并發(fā)性。 方案三,人為自己制造鎖競爭,加劇并發(fā)量。 方案二相對比較好,具體還要結合實際業(yè)務場景。
肉山:
不考慮數(shù)據(jù)表的訪問并發(fā)量,單純從這個三個方案來對比的話。
第一個方案,一次占用的鎖時間較長,可能會導致其他客戶端一直在等待資源。 第二個方案,分成多次占用鎖,串行執(zhí)行,不占有鎖的間隙其他客戶端可以工作,類似于現(xiàn)在多任務操作系統(tǒng)的時間分片調度,大家分片使用資源,不直接影響使用。 第三個方案,自己制造了鎖競爭,加劇并發(fā)。
-------------------------------------------
~嗡嗡:
1. 直接 delete 10000 可能使得執(zhí)行事務時間過長 2. 效率慢點每次循環(huán)都是新的短事務,并且不會鎖同一條記錄,重復執(zhí)行 DELETE 知道影響行為 0 即可 3. 效率雖高,但容易鎖住同一條記錄,發(fā)生死鎖的可能性比較高
作者:_陳哈哈
https://blog.csdn.net/qq_39390545/article/details/107519747
——End——
后臺回復關鍵字:1024,獲取一份精心整理的技術干貨 后臺回復關鍵字:進群,帶你進入高手如云的交流群。 推薦閱讀 這是一個能學到技術的公眾號,歡迎關注
點擊「閱讀原文」了解SQL訓練營
評論
圖片
表情
