Mysql刪除慢怎么解決 mysql刪除數(shù)據(jù)時間長問題

MySQL刪除千萬級數(shù)據(jù)量導(dǎo)致的慢查詢優(yōu)化

有人刪了千萬級的數(shù)據(jù),結(jié)果導(dǎo)致頻繁的慢查詢。

10年積累的成都網(wǎng)站設(shè)計、做網(wǎng)站經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先做網(wǎng)站設(shè)計后付款的網(wǎng)站建設(shè)流程,更有永嘉免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

線上收到大量慢查詢告警,于是檢查慢查詢的SQL,發(fā)現(xiàn)不是啥復(fù)雜SQL,這些SQL主要針對一個表,基本都是單行查詢,看起來應(yīng)該不會有慢查詢。這種SQL基本上都是直接根據(jù)索引查找出來的,性能應(yīng)該極高。

是否可能慢查詢不是SQL問題,而是MySQL生產(chǎn)服務(wù)器的問題?特殊情況下,MySQL出現(xiàn)慢查詢還真不是SQL問題,而是他自己生產(chǎn)服務(wù)器的負(fù)載太高,導(dǎo)致SQL語句執(zhí)行慢。比如現(xiàn)在MySQL服務(wù)器的

磁盤I/O負(fù)載高,每秒執(zhí)行大量高負(fù)載的隨機(jī)I/O,但磁盤本身每秒能執(zhí)行的隨機(jī)I/O有限,導(dǎo)致正常SQL在磁盤執(zhí)行時,若跑一些隨機(jī)IO,你的磁盤太忙,顧不上你了,導(dǎo)致你本來很快的一個SQL,要等很久才能執(zhí)行完畢,這時就可能導(dǎo)致正常SQL也變成慢查詢。

也許網(wǎng)絡(luò)負(fù)載高,導(dǎo)致你一個SQL語句要發(fā)到MySQL,光是等待獲取一個和MySQL的連接,都很難,要等很久或MySQL自己網(wǎng)絡(luò)負(fù)載太高,帶寬打滿,帶寬打滿后,你一個SQL也許執(zhí)行很快,但其查出來的數(shù)據(jù)返回給你,網(wǎng)絡(luò)都送不出去,也會變成慢查詢。

若CPU負(fù)載過高,也會導(dǎo)致CPU過于繁忙去執(zhí)行別的任務(wù),沒時間執(zhí)行你的SQL。

所以慢查詢不一定是SQL本身導(dǎo)致,若覺得SQL不應(yīng)該會慢查詢,結(jié)果他那個時間段跑這個SQL 就是慢,應(yīng)排查當(dāng)時MySQL服務(wù)器的負(fù)載,尤其看看磁盤、網(wǎng)絡(luò)及 CPU 的負(fù)載,是否正常。

當(dāng)某個離線作業(yè)瞬間大批量把數(shù)據(jù)往MySQL里灌入的時,他一瞬間服務(wù)器磁盤、網(wǎng)絡(luò)以及CPU的負(fù)載會超高。

此時你一個正常SQL執(zhí)行下去,短時間內(nèi)一定會慢查詢,類似問題,優(yōu)化手段更多是控制你導(dǎo)致MySQL負(fù)載過高的那些行為,比如灌入大量數(shù)據(jù),最好在業(yè)務(wù)低峰期灌入,別影響高峰期的線上系統(tǒng)運行。

但看了下MySQL服務(wù)器的磁盤、網(wǎng)絡(luò)以及CPU負(fù)載,一切正常,似乎也不是這問題導(dǎo)致??雌饋頍o解了?

慢 SQL 的頭兩步排查手段:

這兩種辦法都不奏效之后,第三步:用MySQL pro?lling工具去細(xì)致的分析SQL語句的執(zhí)行過程和耗時。

這個工具可以對SQL語句的執(zhí)行耗時進(jìn)行非常深入和細(xì)致的分析

打開pro?ling,使用

接著MySQL就會自動記錄查詢語句的pro?ling信息。此時若執(zhí)行show pro?les,就會給你列出各種查詢語句的pro?ling信息,會記錄下來每個查詢語句的query id,所以你要針對你需要分析的query找到對他的query id,我們當(dāng)時就是針對慢查詢的那個SQL語句找到了query id。

然后針對單個查詢語句,看其pro?ling信息,使用show pro?le cpu, block io for query xx,這里的xx是數(shù)字,此時就可以看到具體的pro?le信息。

除了cpu以及block io以外,還能指定去看這個SQL語句執(zhí)行時候的其他各項負(fù)載和耗時。

會給你展示出來SQL語句執(zhí)行時候的各種耗時,比如磁盤IO的耗時,CPU等待耗時,發(fā)送數(shù)據(jù)耗時,拷貝數(shù)據(jù)到臨時表的耗時等,SQL執(zhí)行過程中的各種耗時都會展示。

檢查該SQL語句的pro?ling信息后,發(fā)現(xiàn)問題,其Sending Data耗時最高,幾乎使用1s,占據(jù)SQL執(zhí)行耗時的99%!其他環(huán)節(jié)耗時低可以理解,畢竟這種簡單SQL執(zhí)行速度真的很快,基本就是10ms級別,結(jié)果跑成1s,那肯定Sending Data就是問題根源!

這Sending Data在干啥呢?

MySQL官方釋義:為一個SELECT語句讀取和處理數(shù)據(jù)行,同時發(fā)送數(shù)據(jù)給客戶端的過程,簡單來說就是為你的SELECT語句把數(shù)據(jù)讀出來,同時發(fā)送給客戶端。

但這過程為啥這么慢?pro?ling確實是提供給我們更多的線索了,但似乎還是沒法解決問題。但已經(jīng)捕獲到異常關(guān)鍵點,就是Sending Data的耗時很高!

接著:

看innodb存儲引擎的一些狀態(tài),此時發(fā)現(xiàn)一個奇怪的指標(biāo):history list length,值特別高,達(dá)到上萬。

MVCC就是多個事務(wù)在對同一個數(shù)據(jù), 有人寫,有人讀,此時可以有多種隔離級別,對一個數(shù)據(jù)有個多版本快照鏈條,才能實現(xiàn)MVCC和各種隔離級別。

所以當(dāng)你有大量事務(wù)執(zhí)行時,就會構(gòu)建這種undo多版本快照鏈條,此時history list length就會很高。然后在事務(wù)提交后,會有一個多版本快照鏈條的自動purge清理機(jī)制,清理了,該值就會降低。一般該值不應(yīng)過高,所以注意到第二個線索:history list length過高,即大量的undo多版本鏈條數(shù)據(jù)沒有清理。推測可能有的事務(wù)長時間運行,所以其多版本快照不能被purge清理,進(jìn)而導(dǎo)致history list length過高。

經(jīng)過這倆線索推測,在大量簡單SQL變成慢查詢時,SQL因為Sending Data環(huán)節(jié)異常,耗時過高;同時此時出現(xiàn)一些長事務(wù)長時間運行,大量的頻繁更新數(shù)據(jù),導(dǎo)致有大量undo多版本快照鏈條,還無法purge清理。

因為發(fā)現(xiàn)有大量的更新語句在活躍,而且有那種長期活躍的長事務(wù)一直在跑而沒有結(jié)束,問了下系統(tǒng)負(fù)責(zé)人,在后臺跑了個定時任務(wù):他居然開了一個事務(wù),然后在一個事務(wù)里刪除上千萬數(shù)據(jù),導(dǎo)致該事務(wù)一直在運行。

這種長事務(wù)的運行會導(dǎo)致你刪除時,僅只是對數(shù)據(jù)加了一個刪除標(biāo)記,事實上并沒有徹底刪除。此時你若和長事務(wù)同時運行的其它事務(wù)里再查詢,他在查詢時可能會把那上千萬被標(biāo)記為刪除的數(shù)據(jù)都掃描一遍。因為每次掃描到一批數(shù)據(jù),都發(fā)現(xiàn)標(biāo)記為刪除了,接著就會再繼續(xù)往下掃描,所以才導(dǎo)致一些查詢語句很慢。

那為何你啟動一個事務(wù),在事務(wù)里查詢,憑什么就要去掃描之前那個長事務(wù)標(biāo)記為刪除狀態(tài)的上千萬的垃圾數(shù)據(jù)?講道理,那些數(shù)據(jù)都被刪了,跟你沒關(guān)系了呀,你可以不去掃描他們 嘛!

而問題癥結(jié)在于,那個 刪除千萬級數(shù)據(jù)的事務(wù)是個長事務(wù) !即當(dāng)你啟動新事務(wù)查詢時,那個刪除千萬級數(shù)據(jù)的長事務(wù)一直在運行,它是活躍的!結(jié)合MVCC的Read View機(jī)制,當(dāng)你啟動一個新事務(wù)查詢時,會生成一個Read View。你的新事務(wù)查詢時,會根據(jù)ReadView去判斷哪些數(shù)據(jù)可見及可見的數(shù)據(jù)版本號,因為每個數(shù)據(jù)都有個版本鏈條,有時你能可見的僅是這個數(shù)據(jù)的一個 歷史 版本。

所以正是因為該長事務(wù)一直在運行,還在刪除大量數(shù)據(jù),而且這些數(shù)據(jù)僅是邏輯刪除,所以此時你新開事務(wù)的查詢還是會讀到所有邏輯刪除數(shù)據(jù),也就會出現(xiàn)千萬級的數(shù)據(jù)掃描,導(dǎo)致了慢查詢!

所以禁止在業(yè)務(wù)高峰期運行那種刪除大量數(shù)據(jù)的語句,因為這可能導(dǎo)致一些正常的SQL都變慢查詢,因為那些SQL也許會不斷掃描你標(biāo)記為刪除的大量數(shù)據(jù),好不容易掃描到一批數(shù)據(jù),結(jié)果發(fā)現(xiàn)是標(biāo)記為刪除的,于是繼續(xù)掃描下去,導(dǎo)致慢查詢!

直接kill那個正在刪除千萬級數(shù)據(jù)的長事務(wù),所有SQL很快恢復(fù)正常。此后,大量數(shù)據(jù)清理全部放在凌晨執(zhí)行,那個時候就沒什么人使用系統(tǒng)了,所以查詢也很少。

請教mysql innodb下delete操作巨慢的情況

您好,我覺得刪除操作巨慢的原因可能有以下幾個:

1、刪除的條件判斷占用了很久,比如刪除的條件用不到任何索引且不是主鍵。

2、刪除的表中建立了索引而且數(shù)據(jù)量比較大,每次刪除都要更新很多索引信息。

3、可能單純的刪除的數(shù)據(jù)量比較大。

4、可能數(shù)據(jù)庫同時在執(zhí)行其他消耗很大的操作。

mysql數(shù)據(jù)刪除過慢

300條數(shù)據(jù)就這么慢,還有別人對其做dml操作。 很可能是鎖表了。

mysql 里 delete in 語句暴慢無比 優(yōu)化

十萬級別查詢量 志強e5 cpu 單核100% 超3分鐘才能跑完。

優(yōu)化后10秒內(nèi)可以跑完。

思路 通過臨時表創(chuàng)建索引用 空間換時間避免頻繁讀取原表信息

mysql刪除原則

not exist 比not in執(zhí)行效率高 (線上項目保持正確性,沒有嘗試網(wǎng)上有人推薦使用 not exist 由于改動大沒有嘗試)

truncate 比 delete執(zhí)行效率高

網(wǎng)站題目:Mysql刪除慢怎么解決 mysql刪除數(shù)據(jù)時間長問題
網(wǎng)站URL:http://muchs.cn/article40/dospoho.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供面包屑導(dǎo)航、移動網(wǎng)站建設(shè)Google、網(wǎng)站制作、自適應(yīng)網(wǎng)站靜態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司