鍍金池/ 問答/人工智能  數(shù)據(jù)庫/ mysql的innodb引擎數(shù)據(jù)庫批量刪除大量數(shù)據(jù)很慢

mysql的innodb引擎數(shù)據(jù)庫批量刪除大量數(shù)據(jù)很慢

因?yàn)椴荒苡肨runcate(因?yàn)橹皇莿h除其中少部分?jǐn)?shù)據(jù)),由于要求此表中的數(shù)據(jù)只保留當(dāng)天的數(shù)據(jù),所以每當(dāng)在凌晨的某一時(shí)刻當(dāng)其他程序處理完其中的數(shù)據(jù)后要?jiǎng)h除該表中昨天以及以前的數(shù)據(jù),使用delete刪除表中的上百萬條記錄時(shí),MySQL刪除速度非常緩慢每一萬條記錄需要大概4分鐘左右,這樣刪除所有無用數(shù)據(jù)要達(dá)到八個(gè)小時(shí)以上,這是難以接受的。。
網(wǎng)上搜到此文(http://blog.csdn.net/gao14401...[MSSQL、MySQL 數(shù)據(jù)庫刪除大批量千萬級(jí)百萬級(jí)數(shù)據(jù)的優(yōu)化]
其中說到每次刪除記錄,數(shù)據(jù)庫都要相應(yīng)地更新索引,這是很慢的IO操作,而且后面索引碎片越來越多,就更慢。
我采取其提供的刪除索引再刪除數(shù)據(jù)再重建索引的方法,并沒有發(fā)現(xiàn)刪除速度有提升,而且時(shí)不時(shí)還會(huì)死鎖

我的數(shù)據(jù)表結(jié)構(gòu)如下:

CREATE TABLE `tbplaylog_copy` (
  `Pid` int(11) NOT NULL AUTO_INCREMENT,
  `Company_id` int(11) NOT NULL DEFAULT '0' COMMENT '??id',
  `uid` int(11) NOT NULL COMMENT '"??ID"',
  `Devno` varchar(32) CHARACTER SET utf8 NOT NULL COMMENT '????',
  `Ad` int(11) NOT NULL COMMENT '????',
  `MakeTime` int(11) NOT NULL COMMENT '????',
  `LastTime` int(11) NOT NULL COMMENT '??????',
  `StartTime` int(11) NOT NULL COMMENT '???????(0,24*60)',
  `EndPoint` int(11) NOT NULL COMMENT '????????(0,24*60)',
  `Status` int(11) NOT NULL COMMENT '???1-????0-???',
  `Note` varchar(128) CHARACTER SET utf8 NOT NULL DEFAULT '' COMMENT '????',
  `Valid` int(11) NOT NULL COMMENT '???',
  `Type` int(11) NOT NULL COMMENT '0,???1????2???',
  `PlayStartTime` int(11) NOT NULL DEFAULT '0',
  `PlayEndTime` int(11) NOT NULL DEFAULT '0',
  `DownloadTime` int(11) NOT NULL DEFAULT '0',
  `DeleteTime` int(11) NOT NULL DEFAULT '0',
  `TemplateId` int(11) NOT NULL DEFAULT '0',
  `ad_adnum` int(11) NOT NULL COMMENT '???ad_id',
  `length` int(11) NOT NULL,
  `DownloadPercent` int(11) NOT NULL DEFAULT '0' COMMENT '???????',
  `DownloadSuccess` int(11) NOT NULL DEFAULT '0' COMMENT '\r\n0-??\r\n1-??”',
  `Playlist_id` int(11) NOT NULL,
  `Delete` tinyint(1) NOT NULL DEFAULT '0' COMMENT '1???',
  `Reset` tinyint(1) NOT NULL DEFAULT '0' COMMENT '1???',
  `source` int(2) NOT NULL,
  `distribute` int(2) NOT NULL DEFAULT '-2' COMMENT '0??-2??',
  PRIMARY KEY (`Pid`),
  KEY `starttime` (`StartTime`) USING BTREE,
  KEY `Devno` (`Devno`),
  KEY `playstarttime` (`PlayStartTime`),
  KEY `index_playlist_id` (`Playlist_id`),
  KEY `ad` (`Ad`),
  KEY `company_id` (`Company_id`)
) ENGINE=InnoDB AUTO_INCREMENT=8760113 DEFAULT CHARSET=latin1;

我的刪除語句

DELETE * FROM tbplaylog WHERE tbplaylog.StartTime < ? OR tbplaylog.StartTime > ? ORDER BY Pid LIMIT 10000

數(shù)據(jù)量為1000w條

回答
編輯回答
不討囍

1、刪除今天以前的數(shù)據(jù),那是說每天凌晨刪除昨天數(shù)據(jù)即可,你一天就1000W?刪除也不需要排序,直接delete from table where 。。 limit 1000即可。另外也可以每次刪除更少量的數(shù)據(jù),避免產(chǎn)生鎖,執(zhí)行頻率高一點(diǎn)就行。
2、也可以采用分區(qū)的方式,按天分區(qū),每天刪除過期分區(qū)表

2017年1月22日 16:52