刪除數(shù)據(jù)必然會在數(shù)據(jù)文件中造成不連續(xù)的空白空間,而當插入數(shù)據(jù)時,這些空白空間則會被利用起來.于是造成了數(shù)據(jù)的存儲位置不連續(xù),以及物理存儲順序與理論上的排序順序不同,這種是數(shù)據(jù)碎片.實際上數(shù)據(jù)碎片分為兩種,一種是單行數(shù)據(jù)碎片,另一種是多行數(shù)據(jù)碎片.前者的意思就是一行數(shù)據(jù),被分成N個片段,存儲在N個位置.后者的就是多行數(shù)據(jù)并未按照邏輯上的順序排列.當有大量的刪除和插入操作時,必然會產(chǎn)生很多未使用的空白空間,這些空間就是多出來的額外空間.索引也是文件數(shù)據(jù),所以也會產(chǎn)生索引碎片,理由同上,大概就是順序紊亂的問題.Engine 不同,OPTIMIZE 的操作也不一樣的,MyISAM 因為索引和數(shù)據(jù)是分開的,所以 OPTIMIZE 可以整理數(shù)據(jù)文件,并重排索引。這樣不但會浪費空間,并且查詢速度也更慢。
嘉黎網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)建站!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站設(shè)計等網(wǎng)站項目制作,到程序開發(fā),運營維護。創(chuàng)新互聯(lián)建站2013年開創(chuàng)至今到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)建站。
查看碎片信息:
Index_length 代表索引的總量
Data_free 代表碎片數(shù)量
從information_schema中獲取信息:
碎片整理:
過程時間長短取決于表大小和碎片多少,
返回結(jié)果optimize status OK則整理完成;
樓主的意思應(yīng)該是由于數(shù)據(jù)庫設(shè)計時使用了允許NULL的字段,由于一些不規(guī)范的操作,使得指數(shù)據(jù)庫中存在著一些"空"數(shù)據(jù),這個就是所謂的"碎片"了,這些碎片的存在會影響數(shù)據(jù)庫的查詢效率,不知道我說的是不是樓主的意思?如果是的話,直接DELETE就行,或者優(yōu)化字段.
我們都知道,在mysql (這里只探討innodb) 中delete數(shù)據(jù),并非真實刪除,而是在這行數(shù)據(jù)上打了一個del的標記,所以這行占用的空間也并不會釋放,但是空間可以被復(fù)用,所以期望用delete數(shù)據(jù)來釋放空間的同學可以醒醒了。這樣就造成了空間上的碎片,那么如果干掉這些碎片呢。
這里先說結(jié)論,alter table語句可以觸發(fā)表重建,消除碎片空間。
mysql中的數(shù)據(jù)存儲結(jié)構(gòu)大概是下面這個樣子的
而delete掉的標記會記錄在頭信息中。
做個實驗,看看空間是否真的沒有釋放;
創(chuàng)建一張表user,并插入很多數(shù)據(jù)
查看表的文件大小
再隨便插入幾條
ok這里看到文件大小增加了16k,這是因為mysql的一頁就是16k,所以文件大小是16k、16k的增長的。
這時候我們刪除大量的數(shù)據(jù)再次查看文件大小,仍然是272k,索命,數(shù)據(jù)雖然刪除,但是空間沒有釋放。
這里我們對主鍵執(zhí)行一個alter table語句
再次查看文件大小
ok 文件大小明顯的減少,這里說明主鍵的alter語句會重建表,并且釋放碎片空間;
這時候我們再刪除大量的數(shù)據(jù)再次查看文件大小,這里我們對普通列執(zhí)行一個alter table語句
再次查看文件大小
ok 文件大小明顯的減少,這里說明普通列的alter語句會重建表,并且釋放碎片空間;
可以看到,當前表的碎片率超高了,50.6%。
有三種辦法整理碎片
這三種操作都是先創(chuàng)建一個臨時表復(fù)制完成后再刪除舊表,所以在執(zhí)行操作的過程中磁盤會先增大。
會鎖表
會鎖表
pt-online-schema-change - ALTER tables 無需鎖表。
整理結(jié)果很明顯,整理后碎片率0.3%。
這里有幾個參數(shù)需要介紹一下:
--dry-run
這個參數(shù)不建立觸發(fā)器,不拷貝數(shù)據(jù),也不會替換原表。只是創(chuàng)建和更改新表。
--execute
表明你已經(jīng)閱讀了文檔,并且確認要 alter the table。你必須配置這個參數(shù)來 alter the table。如果你不配置,那么工具將只進行一些安全檢查然后就退出了。這幫助確保你已經(jīng)閱讀了文檔,并且了解如何使用該工具。如果你沒有閱讀這些文檔,那么不會設(shè)置該參數(shù)。
--critical-load
每次chunk操作前后,會根據(jù)show global status統(tǒng)計指定的狀態(tài)量的變化,默認是統(tǒng)計Thread_running。目的是為了安全,防止原始表上的觸發(fā)器引起負載過高。這也是為了防止在線DDL對線上的影響。超過設(shè)置的閥值,就會終止操作,在線DDL就會中斷。提示的異常如上報錯信息。
--max-lag
type: time; default: 1s
lag 滯后偏移
暫停數(shù)據(jù)拷貝,直到所有replicas的lag值低于該值。在每個 data-copy query (each chunk)后,工具會通過Seconds_Behind_Master查詢所有replica的 replication lag 。如果任何replica lag大于該值,那么工具會sleep --check-interval 秒,然后再次檢查所有replica。如果你指定 --check-slave-lag ,那么工具會檢查那臺server,而不是所有server。如果你想控制哪個提供工具的監(jiān)控,配置DSN值 --recursion-method 。
工具會等待直到replicas停止lagging。如果任一replica停止,工具會一直處于等待狀態(tài)直到該replica啟動。 在所有replicas運行并且lagging不大的情況下,數(shù)據(jù)拷貝繼續(xù)。
工具在等待的時候,會打印進程報告。如果replica停止了,會立即打印進程報告,然后在每個進程報告期間重復(fù)。
--check-interval
type: time; default: 1
Sleep time between checks for --max-lag .
--max-load
選項定義一個閥值,在每次chunk操作后,查看show global status狀態(tài)值是否高于指定的閥值。該參數(shù)接受一個mysql status狀態(tài)變量以及一個閥值,如果沒有給定閥值,則定義一個閥值為為高于當前值的20%。注意這個參數(shù)不會像--critical-load終止操作,而只是暫停操作。當status值低于閥值時,則繼續(xù)往下操作。是暫停還是終止操作這是--max-load和--critical-load的差別。
--charset
簡寫: -A; type: string
設(shè)置默認字符集。如果值為 utf8,設(shè)置 Perl’s binmode on STDOUT to utf8,傳送 mysql_enable_utf8 參數(shù)到 DBD::mysql,然后在連接到MySQL后運行 SET NAMES UTF8 。其他的值也是在STDOUT設(shè)置 binmode,然后在連到MySQL后運行 SET NAMES 。
--check-replication-filters
檢查復(fù)制中是否設(shè)置了過濾條件,如果設(shè)置了,程序?qū)⑼顺?/p>
--nocheck-replication-filters
不檢查復(fù)制中是否設(shè)置了過濾條件
--set-vars
設(shè)置mysql的變量值
--check-slave-lag
檢查主從延遲
--no-version-check
不檢查版本,在阿里云服務(wù)器中一般加入此參數(shù),否則會報錯