2017-09-25 50 views
0

在將其標記爲重複之前,請先閱讀整個問題。MyISAM/InnoDB從文件中刪除特定文本的有效方式是什麼?

我知道我們只有一種方法可以從C中的文件中刪除特定的文本,即通過重寫除了我們想要刪除的文本之外的整個文件。但是如果我們有一個文件,這種方法不會很有效數千或數百萬行文字。現在,由於MyISAM是一個存儲引擎,因爲它被用於數百萬條記錄,並且它是用C語言編寫的,所以它不需要重寫整個文件就可以實現這種效率。我問的是MyISAM開發人員用來從文件中刪除特定文本而不重新寫入的技術。

+1

不標記爲重複,但vtc爲「太寬」代替。我們不能解釋數據庫:( –

+0

@MartinJames能否請你簡單解釋一下,我只是要求開發人員使用的解決方案來克服重寫文件的問題。 –

+0

同意@MartinJames。不可能簡短回答。MySQL引擎是許多年和許多開發者的效果(在保證金上:年份乘以人 - 在「開發人員英語」中如何說?) - 我不是非英語的母語) –

回答

1

就像在DOS中一樣,事情並沒有被「刪除」,而是被「標記爲刪除」,這樣對於所有後續操作,刪除的內容似乎都消失了。

的MyISAM:

  • 馬克的紀錄,以表明它「被刪除」的第一個字節。
  • 從每個索引中刪除適當的條目。

InnoDB的:

  • 轉到塊(在B樹數據,由PRIMARY KEY索引)包含行刪除;將其標記爲已刪除。
  • 添加東西到重做/撤銷日誌 - 萬一後續ROLLBACK復活行。
  • 將條目添加到更改緩衝區,以便索引查找不會找到該行。
  • 最終將更改緩衝區條目刷新爲實際索引。
  • 最終清除數據塊中的數據記錄。

在任一引擎中,將只有少數IOP(BTree鑽取,讀取,寫入,日誌記錄)來刪除該行。實際的IOP數量取決於緩存 - 由於將此刪除與表格上的其他操作結合在一起。

MyISAM的數據是一個流文件;代碼將「查找」+讀取或寫入一條記錄。

MyISAM的索引是BTrees並緩存在「key_buffer」(1KB塊)中; InnoDB的數據和索引是BTrees,並緩存在「buffer_pool」(16KB塊)中。所有操作都是查找+讀/寫一個塊。

InnoDB重做/撤銷日誌,我認爲是流式傳輸。

InnoDB的「雙寫」緩衝區是一個冗餘寫入的塊。這是一種針對「破損頁面」的ACID保護,其中在停電期間塊被寫入一半。大多數磁盤上的操作單元是一個512字節的「扇區」; MyISAM/InnoDB的單位有幾個。

從長遠看

所以,如果因爲刪除的記錄只標明,是磁盤空間不斷恢復?我強調「內存」RAM上的磁盤空間,因爲RAM只是用作緩存。

嗯,這取決於。如果您正在「攪動」數據 - 刪除和插入 - 則DELETE釋放的空間可用於INSERT。但是,由於記錄的佈局方式,INSERT可能會也可能不會重複使用最近由DELETE釋放的空間。但是,從長遠來看,插入將填補刪除留下的「漏洞」。但...

BTrees天生就有一個小問題。每個節點都是固定大小的塊。做了幾次刪除之後,固定大小沒有縮小。插入太多後,該塊被「分割」成兩個塊(具有相同的,固定的大小)。不過,隨着時間的推移,BTree將會傾向於大約69%的完整。也就是說,以69塊滿塊開始的情況(在大量流失之後)將達到約100塊的穩定狀態,同時仍包含相同數量的記錄。

所以,一張表會增長,但從不縮水。但增長限於實際數據大小的幾倍。如何收縮?...

在MyISAM和InnoDB中,都有自動的方式來「碎片整理」並將浪費的空間還給操作系統。但是,有一條SQL語句可以這樣做。但不要使用它;這是不值得的努力。它創建一個新表,複製所有數據,重建索引並將表重命名爲您所擁有的數據。很多努力;幾乎沒有太大的好處。

另一件事......如果兩個'相鄰'BTree塊少於半滿,塊將被組合。 (這樣可以釋放一個在給定表中重用的塊,但不會返回給操作系統。)

「大公司」做什麼?答:「沒有。」我曾經爲此工作過,所以我可以從經驗中發言。在100個系統上的10,000個表中,我只識別出碎片整理值得去做的兩種情況。只有每月。而MyISAM,而不是InnoDB。你今天不應該使用MyISAM。

+0

所以這意味着數據並未真正被刪除,而是被標記爲已刪除並從閱讀中跳過。在這種情況下,內存不會被釋放,這將是這些存儲引擎的缺點之一,並且從長遠來看,將需要重寫該文件以釋放內存。我是對的嗎?這麼做(重寫一次很長時間)真的發生在像谷歌和臉書這樣的大公司? –

+1

@ChaitanyaVaishampayan - 添加了一條評論 –

相關問題