<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          delete后加 limit是個(gè)好習(xí)慣么 !

          共 2809字,需瀏覽 6分鐘

           ·

          2020-12-20 03:10




          作者:_陳哈哈

          https://blog.csdn.net/qq_39390545/article/details/107519747

          在業(yè)務(wù)場(chǎng)景要求高的數(shù)據(jù)庫(kù)中,對(duì)于單條刪除和更新操作,在 delete 和 update 后面加 limit 1 絕對(duì)是個(gè)好習(xí)慣。比如,在刪除執(zhí)行中,第一條就命中了刪除行,如果 SQL 中有 limit 1;這時(shí)就 return 了,否則還會(huì)執(zhí)行完全表掃描才 return。效率不言而喻。

          那么,在日常執(zhí)行 delete 時(shí),我們是否需要養(yǎng)成加 limit 的習(xí)慣呢?是不是一個(gè)好習(xí)慣呢?

          在日常的 SQL 編寫中,你寫 delete 語(yǔ)句時(shí)是否用到過以下 SQL?

          delete from t where sex = 1 limit 100;?

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

          寫在前面,如果是清空表數(shù)據(jù)建議直接用 truncate,效率上 truncate 遠(yuǎn)高于 delete,應(yīng)為 truncate 不走事務(wù),不會(huì)鎖表,也不會(huì)生產(chǎn)大量日志寫入日志文件;truncate table table_name 后立刻釋放磁盤空間,并重置 auto_increment 的值。delete 刪除不釋放磁盤空間,但后續(xù) insert 會(huì)覆蓋在之前刪除的數(shù)據(jù)上。詳細(xì)了解請(qǐng)?zhí)D(zhuǎn)另一篇博文《delete、truncate、drop 的區(qū)別有哪些,該如何選擇》

          下面只討論 delete 場(chǎng)景,首先,delete 后面是支持 limit 關(guān)鍵字的,但僅支持單個(gè)參數(shù),也就是 [limit row_count],用于告知服務(wù)器在控制命令被返回到客戶端前被刪除的行的最大值。

          delete limit 語(yǔ)法如下,值得注意的是,order by 必須要和 limit 聯(lián)用,否則就會(huì)被優(yōu)化掉。

          delete \[low\_priority\] \[quick\] \[ignore\] from tbl\_name
          \[where ...\]
          \[order by ...\]
          \[limit row\_count\]

          加 limit 的的優(yōu)點(diǎn):

          以下面的這條 SQL 為例:

          delete from t where sex = 1;?

          • 1. 降低寫錯(cuò) SQL 的代價(jià),就算刪錯(cuò)了,比如 limit 500, 那也就丟了 500 條數(shù)據(jù),并不致命,通過 binlog 也可以很快恢復(fù)數(shù)據(jù)。

          • 2. 避免了長(zhǎng)事務(wù),delete 執(zhí)行時(shí) MySQL 會(huì)將所有涉及的行加寫鎖和 Gap 鎖(間隙鎖),所有 DML 語(yǔ)句執(zhí)行相關(guān)行會(huì)被鎖住,如果刪除數(shù)量大,會(huì)直接影響相關(guān)業(yè)務(wù)無(wú)法使用。

          • 3. delete 數(shù)據(jù)量大時(shí),不加 limit 容易把 cpu 打滿,導(dǎo)致越刪越慢。

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


          對(duì)于 delete limit 的使用,MySQL 大佬丁奇有一道題:

          如果你要?jiǎng)h除一個(gè)表里面的前 10000 行數(shù)據(jù),有以下三種方法可以做到:
          第一種,直接執(zhí)行 delete from T limit 10000;
          第二種,在一個(gè)連接中循環(huán)執(zhí)行 20 次 delete from T limit 500;
          第三種,在 20 個(gè)連接中同時(shí)執(zhí)行 delete from T limit 500。

          你先考慮一下,再看看幾位老鐵的回答:

          --------------------------------------------

          Tony Du:

          • 方案一,事務(wù)相對(duì)較長(zhǎng),則占用鎖的時(shí)間較長(zhǎng),會(huì)導(dǎo)致其他客戶端等待資源時(shí)間較長(zhǎng)。

          • 方案二,串行化執(zhí)行,將相對(duì)長(zhǎng)的事務(wù)分成多次相對(duì)短的事務(wù),則每次事務(wù)占用鎖的時(shí)間相對(duì)較短,其他客戶端在等待相應(yīng)資源的時(shí)間也較短。這樣的操作,同時(shí)也意味著將資源分片使用(每次執(zhí)行使用不同片段的資源),可以提高并發(fā)性。

          • 方案三,人為自己制造鎖競(jìng)爭(zhēng),加劇并發(fā)量。

          • 方案二相對(duì)比較好,具體還要結(jié)合實(shí)際業(yè)務(wù)場(chǎng)景。

          --------------------------------------------
          肉山:
          不考慮數(shù)據(jù)表的訪問并發(fā)量,單純從這個(gè)三個(gè)方案來對(duì)比的話。

          • 第一個(gè)方案,一次占用的鎖時(shí)間較長(zhǎng),可能會(huì)導(dǎo)致其他客戶端一直在等待資源。

          • 第二個(gè)方案,分成多次占用鎖,串行執(zhí)行,不占有鎖的間隙其他客戶端可以工作,類似于現(xiàn)在多任務(wù)操作系統(tǒng)的時(shí)間分片調(diào)度,大家分片使用資源,不直接影響使用。

          • 第三個(gè)方案,自己制造了鎖競(jìng)爭(zhēng),加劇并發(fā)。

          至于選哪一種方案要結(jié)合實(shí)際場(chǎng)景,綜合考慮各個(gè)因素吧,比如表的大小,并發(fā)量,業(yè)務(wù)對(duì)此表的依賴程度等。
          -------------------------------------------
          ~嗡嗡:

          • 1. 直接 delete 10000 可能使得執(zhí)行事務(wù)時(shí)間過長(zhǎng)

          • 2. 效率慢點(diǎn)每次循環(huán)都是新的短事務(wù),并且不會(huì)鎖同一條記錄,重復(fù)執(zhí)行 DELETE 知道影響行為 0 即可

          • 3. 效率雖高,但容易鎖住同一條記錄,發(fā)生死鎖的可能性比較高

          -------------------------------------------

          怎么刪除表的前 10000 行。比較多的朋友都選擇了第二種方式,即:在一個(gè)連接中循環(huán)執(zhí)行 20 次 delete from T limit 500。確實(shí)是這樣的,第二種方式是相對(duì)較好的。

          第一種方式(即:直接執(zhí)行 delete from T limit 10000)里面,單個(gè)語(yǔ)句占用時(shí)間長(zhǎng),鎖的時(shí)間也比較長(zhǎng);而且大事務(wù)還會(huì)導(dǎo)致主從延遲。

          第三種方式(即:在 20 個(gè)連接中同時(shí)執(zhí)行 delete from T limit 500),會(huì)人為造成鎖沖突。

          這個(gè)例子對(duì)我們實(shí)踐的指導(dǎo)意義就是,在刪除數(shù)據(jù)的時(shí)候盡量加 limit。這樣不僅可以控制刪除數(shù)據(jù)的條數(shù),讓操作更安全,還可以減小加鎖的范圍。所以,在 delete 后加 limit 是個(gè)值得養(yǎng)成的好習(xí)慣。

          好了,本文就帶你了解這些,如果有相關(guān)疑問和好想法,請(qǐng)?jiān)谙路搅粞裕奖愫托』锇閮簜円黄鹩懻摗?/p>

          更多好文章

          1. Java高并發(fā)系列(共34篇)
          2. MySql高手系列(共27篇)
          3. Maven高手系列(共10篇)
          4. Mybatis系列(共12篇)
          5. 聊聊db和緩存一致性常見的實(shí)現(xiàn)方式
          6. 接口冪等性這么重要,它是什么?怎么實(shí)現(xiàn)?
          7. 泛型,有點(diǎn)難度,會(huì)讓很多人懵逼,那是因?yàn)槟銢]有看這篇文章!

          瀏覽 78
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本国产精品高朝 | 久久久6| jiZZ亚洲女人高潮大叫 | 少妇大战28厘米黑人 | 看黄色操逼视频 |