1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        delete 后加 limit 真的是個好習(xí)慣嗎?

        共 2865字,需瀏覽 6分鐘

         ·

        2021-02-02 06:38


        點(diǎn)擊上方?藍(lán)字?關(guān)注我們!



        Java,Python,C/C++,Linux,PHP,Go,C#,QT,大數(shù)據(jù),算法,軟件教程,前端,簡歷,畢業(yè)設(shè)計等分類,資源在不斷更新中... 點(diǎn)擊領(lǐng)取!

        每天 11 點(diǎn)更新文章,餓了點(diǎn)外賣,點(diǎn)擊 ??《無門檻外賣優(yōu)惠券,每天免費(fèi)領(lǐng)!》


        在業(yè)務(wù)場景要求高的數(shù)據(jù)庫中,對于單條刪除和更新操作,在delete和update后面加limit 1絕對是個好習(xí)慣。

        比如,在刪除執(zhí)行中,第一條就命中了刪除行,如果SQL中有l(wèi)imit 1;這時就return了,否則還會執(zhí)行完全表掃描才return。效率不言而喻。

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

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

        delete?from?t?where?sex?=?1?limit?100;?

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

        寫在前面,如果是清空表數(shù)據(jù)建議直接用truncate,效率上truncate遠(yuǎn)高于delete,應(yīng)為truncate不走事務(wù),不會鎖表,也不會生產(chǎn)大量日志寫入日志文件;truncate table table_name 后立刻釋放磁盤空間,并重置auto_increment的值。

        delete刪除不釋放磁盤空間,但后續(xù)insert會覆蓋在之前刪除的數(shù)據(jù)上。詳細(xì)了解:

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

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

        delete limit語法如下:

        (值得注意的是,當(dāng)需要用到order by排序時,必須order by + limit聯(lián)用,否則order by 就會被優(yōu)化器優(yōu)化掉,被認(rèn)為無意義。)

        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. 降低寫錯SQL的代價,就算刪錯了,比如limit 500,那也就丟了500條數(shù)據(jù),并不致命,通過binlog也可以很快恢復(fù)數(shù)據(jù)。

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

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

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


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

        如果你要刪除一個表里面的前 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。

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


        Tony Du:
        • 方案一,事務(wù)相對較長,則占用鎖的時間較長,會導(dǎo)致其他客戶端等待資源時間較長。

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

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

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


        肉山:

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

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

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

        • 第三個方案,自己制造了鎖競爭,加劇并發(fā)。

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


        ~嗡嗡:

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

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

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


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

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

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

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

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

        往期推薦

        Java 項(xiàng)目實(shí)戰(zhàn)天天酷跑

        推薦幾個 JVM 內(nèi)存工具,建議收藏!

        周末了,給自己加個大大的雞腿!

        MyBatis的動態(tài)代理實(shí)現(xiàn)機(jī)制

        看完文章,餓了點(diǎn)外賣,點(diǎn)擊 ??《無門檻外賣優(yōu)惠券,每天免費(fèi)領(lǐng)!》

        END



        若覺得文章對你有幫助,隨手轉(zhuǎn)發(fā)分享,也是我們繼續(xù)更新的動力。


        長按二維碼,掃掃關(guān)注哦

        ?「C語言中文網(wǎng)」官方公眾號,關(guān)注手機(jī)閱讀教程??


        必備編程學(xué)習(xí)資料


        目前收集的資料包括:?Java,Python,C/C++,Linux,PHP,go,C#,QT,git/svn,人工智能,大數(shù)據(jù),單片機(jī),算法,小程序,易語言,安卓,ios,PPT,軟件教程,前端,軟件測試,簡歷,畢業(yè)設(shè)計,公開課?等分類,資源在不斷更新中...


        點(diǎn)擊“閱讀原文”,立即免費(fèi)領(lǐng)取最新資料!
        ??????
        瀏覽 29
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            秋霞电影院午夜伦 | 亚洲人成77777 | 农村三级片 | 欧美老熟妇性生交大片A片斗地主 | 粉嫩小泬BBBB免费观看 | 无毛少妇mp9 | 成人片在线播放高清无码 | 精品一区二区三区免费毛片 | 艹逼网站 | 69国产视频 |