我們?cè)诠ぷ髦袝r(shí)常會(huì)遇到一些客戶的TPS/QPS都不太高,但磁盤占用非常大,一旦單實(shí)例空間太大,像內(nèi)存、網(wǎng)絡(luò)、CPU以及備份都將增加相應(yīng)的開銷。可能僅僅是由于空間不滿足使得我們不得不進(jìn)行擴(kuò)容,下面的方法提供給大家參考。有則改之無(wú)則加勉。
1、表結(jié)構(gòu)設(shè)計(jì)上
1) 字符集是否遵循了最小化原則?(能用latin的就不用gbk。能用gbk的就不用utf8)
2) 索引上是否有濫用?(根本不使用的字段建索引、不適合建索引的字段建索引、重復(fù)建索引或者不能很好的利用前綴索引等)
3) 冗余字段是否太多?(各表中不用的或者字段冗余太多)
4) 不正確的字段類型?(能用1個(gè)字節(jié)非要用幾個(gè)字節(jié),像枚舉類、狀態(tài)類比較常見)
5) 將較長(zhǎng)的字段或者幾個(gè)字段組合做為主鍵?(主鍵最好用mysql自增)
具體事例如下:
| CREATE TABLE `class_meta` (`class_name` varchar(128) NOT NULL COMMENT '類名',`class_desc` varchar(2048) default '' COMMENT '類的描述',`class_status` char(20) default 'test1' COMMENT 'test1,test2',PRIMARY KEY (`class_name`),UNIQUE KEY `cm_cn_uk` (`class_name`),KEY `cm_cd_ind` (`class_desc`(767)),KEY `cm_cs_ind` (`class_status`),KEY `cm_cdcn_ind` (`class_desc`(767),`class_name`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='meta信息'; |
通過(guò)上面的表結(jié)構(gòu)能看到如下地方不合適
1、主鍵與唯一索引明顯重復(fù),索引cm_cd_ind與索引cm_cdcn_ind索引重復(fù)(這種情況經(jīng)常出現(xiàn),大家留意下)
2、cm_cs_ind如果兩個(gè)狀態(tài)分布均勻也明顯不合適建索引
3、class_desc由于是描述性質(zhì)的,也不合適建索引
4、最好以自增做為主鍵,可以減少整表的空間
5、class_status列明顯可以用tinyint來(lái)存,可以省下19個(gè)字節(jié)
2、存儲(chǔ)內(nèi)容上
1) 是否將圖片、視頻、音樂(lè)等大數(shù)據(jù)存儲(chǔ)在表中?(表里最好只保留路徑而不是實(shí)際的文件內(nèi)容)
3、數(shù)據(jù)保留上
1)是否有已過(guò)期而未刪除的數(shù)據(jù)?(對(duì)于無(wú)效數(shù)據(jù)及時(shí)清理或者進(jìn)行歷史歸檔)
4、后期維護(hù)上
1)是否對(duì)經(jīng)常刪除的表進(jìn)行維護(hù)(optimize table)
建議:
1、在性能要求不高的case中(并發(fā)不太高),可以考慮使用壓縮表。一般壓縮率在30%-70%之間,收益非常可觀。
2、對(duì)于刪除非常頻繁的表要定期進(jìn)行優(yōu)化,使表中碎片減少。提高查詢、寫入的性能。
3、在表結(jié)構(gòu)設(shè)計(jì)上,一定要發(fā)揚(yáng)“斤斤計(jì)較”的精神,能用1個(gè)字節(jié)表示的堅(jiān)決不用2個(gè)字節(jié)。
4、盡量減少大字段的使用。
ps:經(jīng)常在跟開發(fā)評(píng)審表結(jié)構(gòu)的時(shí)候,時(shí)常會(huì)被笑話說(shuō)DBA太摳門,一點(diǎn)都不大氣。當(dāng)數(shù)據(jù)量小的時(shí)候可能大家不覺得,但當(dāng)你的數(shù)據(jù)級(jí)到T或者P的時(shí)候,哪怕多省幾個(gè)字節(jié)都是非常可觀的,給大家簡(jiǎn)單算筆賬,如果我們將一張5億條記錄的表,字段從100個(gè)字節(jié)降到60個(gè)字節(jié)(應(yīng)該很容易做到吧),那么不算上索引將節(jié)約大約18G的空間。
新聞熱點(diǎn)
疑難解答
圖片精選