新聞中心
【獨家譯文】本文淺析MySQL數(shù)據(jù)碎片的產(chǎn)生:定義,時間及成因。

十年的龍華網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。網(wǎng)絡(luò)營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整龍華建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)從事“龍華網(wǎng)站設(shè)計”,“龍華網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。
MySQL列表,包括MyISAM和InnoDB這兩種最常見的類型,而根據(jù)經(jīng)驗來說,其碎片的產(chǎn)生及消除都是隨機的。碎片會在你的表格中留下明顯的空白,而這會給列表掃描工作帶來相當(dāng)大的困擾。對你的列表進行優(yōu)化,這樣會使列表的全面及分區(qū)掃描工作進行得更有效率。
碎片——實例
MySQL具有相當(dāng)多不同種類的存儲引擎來實現(xiàn)列表中的數(shù)據(jù)存儲功能。每當(dāng)MySQL從你的列表中刪除了一行內(nèi)容,該段空間就會被留空。而在一段時間內(nèi)的大量刪除操作,會使這種留空的空間變得比存儲列表內(nèi)容所使用的空間更大。當(dāng)MySQL對數(shù)據(jù)進行掃描時,它掃描的對象實際是列表的容量需求上限,也就是數(shù)據(jù)被寫入的區(qū)域中處于峰值位置的部分。如果進行新的插入操作,MySQL將嘗試利用這些留空的區(qū)域,但仍然無法將其徹底占用。
這種額外的破碎的存儲空間在讀取效率方面比正常占用的空間要低得多。讓我們看一個實例。
我們將創(chuàng)建一個數(shù)據(jù)庫(有時也稱其為大綱)及一個測試用的列表:
- (root@localhost) [test]> create database frag_test;
- Query OK, 1 row affected (0.03 sec)
- (root@localhost) [test]> use frag_test;
- Database changed
- (root@localhost) [frag_test]> create table frag_test (c1 varchar(64));
- Query OK, 0 rows affected (0.05 sec)
現(xiàn)在讓我們在列表中加入如下幾行:
- (root@localhost) [frag_test]> insert into frag_test values ('this is row 1');
- Query OK, 1 row affected (0.01 sec)
- (root@localhost) [frag_test]> insert into frag_test values ('this is row 2');
- Query OK, 1 row affected (0.00 sec)
- (root@localhost) [frag_test]> insert into frag_test values ('this is row 3');
- Query OK, 1 row affected (0.00 sec)
現(xiàn)在我們進行碎片查看:
- (root@localhost) [frag_test]> show table status from frag_test\G;
- *************************** 1. row ***************************
- Name: frag_test
- Engine: MyISAM
- Version: 10
- Row_format: Dynamic
- Rows: 3
- Avg_row_length: 20
- Data_length: 60
- Max_data_length: 281474976710655
- Index_length: 1024
- Data_free: 0
- Auto_increment: NULL
- Create_time: 2011-02-23 14:55:27
- Update_time: 2011-02-23 15:06:55
- Check_time: NULL
- Collation: latin1_swedish_ci
- Checksum: NULL
- Create_options:
- Comment:
- 1 row in set (0.00 sec)
現(xiàn)在我們刪除一行,并再次檢測:
- (root@localhost) [frag_test]> delete from frag_test where c1 = 'this is row 2';
- Query OK, 1 row affected (0.00 sec)
- (root@localhost) [frag_test]> show table status from frag_test\G;
- *************************** 1. row ***************************
- Name: frag_test
- Engine: MyISAM
- Version: 10
- Row_format: Dynamic
- Rows: 2
- Avg_row_length: 20
- Data_length: 60
- Max_data_length: 281474976710655
- Index_length: 1024
- Data_free: 20
- Auto_increment: NULL
- Create_time: 2011-02-23 14:55:27
- Update_time: 2011-02-23 15:07:49
- Check_time: NULL
- Collation: latin1_swedish_ci
- Checksum: NULL
- Create_options:
- Comment:
- 1 row in set (0.00 sec)
需要注意的是,“data_free”一欄顯示出了我們刪除第二行后所產(chǎn)生的留空空間。想象一下如果你有兩萬行指令的話,結(jié)果是什么樣的。以此推算,它們將耗費四十萬字節(jié)的存儲空間?,F(xiàn)在如果你將兩萬條命令行刪到只剩一行,列表中有用的內(nèi)容將只占二十字節(jié),但MySQL在讀取中會仍然將其視同于一個容量為四十萬字節(jié)的列表進行處理,并且除二十字節(jié)以外,其它空間都被白白浪費了。
清理碎片
幸運的是一旦你鎖定了這一問題,MySQL提供了一種簡便的修正方法。這就是所謂的優(yōu)化列表,具體內(nèi)容如下:
- (root@localhost) [frag_test]> optimize table frag_test;
- +---------------------+----------+----------+----------+
- | Table | Op | Msg_type | Msg_text |
- +---------------------+----------+----------+----------+
- | frag_test.frag_test | optimize | status | OK |
- +---------------------+----------+----------+----------+
- 1 row in set (0.00 sec)
- (root@localhost) [frag_test]> show table status from frag_test\G;
- *************************** 1. row ***************************
- Name: frag_test
- Engine: MyISAM
- Version: 10
- Row_format: Dynamic
- Rows: 2
- Avg_row_length: 20
- Data_length: 40
- Max_data_length: 281474976710655
- Index_length: 1024
- Data_free: 0
- Auto_increment: NULL
- Create_time: 2011-02-23 14:55:27
- Update_time: 2011-02-23 15:11:05
- Check_time: 2011-02-23 15:11:05
- Collation: latin1_swedish_ci
- Checksum: NULL
- Create_options:
- Comment:
- 1 row in set (0.00 sec)
性能考量
“優(yōu)化列表”功能在進行中會對整個列表進行鎖定。對于小型列表,這一功能的效果非常好,因為整個列表的讀取和修改速度都會很快。但對于那些體積巨大的列表來說,這一過程將消耗很長時間,并且其間會中斷或減少可用的應(yīng)用程序數(shù)量。怎么辦?
再一次,MySQL幸運地提供了一項堪稱偉大的功能,名為“主-主復(fù)制”。在這種配置之下,你的后臺數(shù)據(jù)庫實際上成為兩個單獨的數(shù)據(jù)庫,一個主動可調(diào)用的,一個被動可調(diào)整的。這兩個數(shù)據(jù)庫在各方面來說都是完全相同的。要實現(xiàn)各種在線操作——包括“優(yōu)化列表”操作——只需在你的被動數(shù)據(jù)庫中即可進行。這將不會對你的應(yīng)用程序造成絲毫影響。一旦優(yōu)化操作完成,主、被動數(shù)據(jù)庫將互相轉(zhuǎn)換,以便應(yīng)用程序直接指向二號數(shù)據(jù)庫,對還未進行優(yōu)化的主動數(shù)據(jù)庫部分自動開始優(yōu)化工作。
這時,兩套數(shù)據(jù)庫的角色已經(jīng)互換,而應(yīng)用程序也將順利指向二號數(shù)據(jù)庫,執(zhí)行與在一號數(shù)據(jù)庫上相同的列表優(yōu)化。而現(xiàn)在主動已經(jīng)轉(zhuǎn)換為被動,因此不會中斷主要任務(wù)處理。
其它命令
顯示你數(shù)據(jù)庫中存在碎片的全部列表:
- (root@localhost) [(none)]> select table_schema, table_name, data_free, engine from information_schema.tables where table_schema not in ('information_schema', 'mysql') and data_free > 0;
- +--------------+-----------------------------+-----------+--------+
- | table_schema | table_name | data_free | engine |
- +--------------+-----------------------------+-----------+--------+
- | aitc | wp_comments | 346536 | MyISAM |
- | aitc | wp_options | 64308 | MyISAM |
- | aitc | wp_postmeta | 124 | MyISAM |
- | cactidb | poller_item | 160 | MyISAM |
- | cactidb | poller_output | 384 | MyISAM |
- | drupal | sessions | 30976 | MyISAM |
- | drupal | users | 92 | MyISAM |
- | drupal | variable | 20 | MyISAM |
- | gg | wp_comments | 232 | MyISAM |
- | gg | wp_options | 696 | MyISAM |
- | gg | wp_postmeta | 560 | MyISAM |
- | ihi | wp_comments | 536 | MyISAM |
- | ihi | wp_options | 444 | MyISAM |
- | ihi | wp_postmeta | 288 | MyISAM |
- | ihi | wp_redirection_items | 1292 | MyISAM |
- | ihi | wp_redirection_logs | 140352 | MyISAM |
- | nds | wp_comments | 4704 | MyISAM |
- | nds | wp_options | 150580 | MyISAM |
- | nds | wp_postmeta | 76 | MyISAM |
- | oos | wp_comments | 317124 | MyISAM |
- | oos | wp_options | 88196 | MyISAM |
- | oos | wp_postmeta | 76 | MyISAM |
- | phplist | phplist_listuser | 252 | MyISAM |
- | phplist | phplist_sendprocess | 52 | MyISAM |
- | phplist | phplist_user_user | 32248 | MyISAM |
- | phplist | phplist_user_user_attribute | 120 | MyISAM |
- | phplist | phplist_user_user_history | 288 | MyISAM |
- | phplist | phplist_usermessage | 1428 | MyISAM |
- | pn_nds | nuke_session_info | 12916 | MyISAM |
- | psa | exp_event | 10024 | MyISAM |
- | test | active_sessions | 30144 | MyISAM |
- +--------------+-----------------------------+-----------+--------+
- 31 rows in set (0.26 sec)
如果你更改了某個列表的存儲引擎,你也應(yīng)該對這一列表進行碎片清理。這是因為MySQL的工作原理導(dǎo)致其必須讀取整個列表,然后利用新的存儲引擎將內(nèi)容寫回磁盤,而在此過程中碎片所在的位置及影響到的數(shù)據(jù)都對執(zhí)行效率造成了嚴重的不良影響。
上述情況如下所示:
- (root@localhost) [frag_test]> alter table frag_test engine = innodb;
- Query OK, 2 rows affected (0.17 sec)
- Records: 2 Duplicates: 0 Warnings: 0
- (root@localhost) [frag_test]> show table status from frag_test
- -> \G;
- *************************** 1. row ***************************
- Name: frag_test
- Engine: InnoDB
- Version: 10
- Row_format: Compact
- Rows: 2
- Avg_row_length: 8192
- Data_length: 16384
- Max_data_length: 0
- Index_length: 0
- Data_free: 0
- Auto_increment: NULL
- Create_time: 2011-02-23 15:41:12
- Update_time: NULL
- Check_time: NULL
- Collation: latin1_swedish_ci
- Checksum: NULL
- Create_options:
- Comment: InnoDB free: 7168 kB
- 1 row in set (0.00 sec)
結(jié)論
如果你發(fā)現(xiàn)一些列表中包含了大量的數(shù)據(jù)留空現(xiàn)象,那么對其進行優(yōu)化是絕對值得的,因為這一過程會大大提升列表的讀取性能及應(yīng)用表現(xiàn)。
原文地址:http://www.databasejournal.com/features/mysql/article.php/3927871/article.htm
【編輯推薦】
- MySQL數(shù)據(jù)庫的優(yōu)化(下)MySQL數(shù)據(jù)庫的高可用架構(gòu)方案
- MySQL數(shù)據(jù)庫的優(yōu)化(上)單機MySQL數(shù)據(jù)庫的優(yōu)化
- MySQL技巧:結(jié)合相關(guān)參數(shù) 做好Limit優(yōu)化
- 詳解MySQL limit查詢優(yōu)化的實際操作步驟
文章題目:淺析MySQL數(shù)據(jù)碎片的產(chǎn)生
鏈接分享:http://www.dlmjj.cn/article/dhgjphg.html


咨詢
建站咨詢
