2

我将android设备发送的时间戳和一些相关的用户数据存储在一个MySQL表中,其结构如下:

CREATE TABLE IF NOT EXISTS `breadcrumbs` (   
  `breadcrumbs_id` bigint(20) NOT NULL AUTO_INCREMENT,   
  `users_id` int(10) NOT NULL,   
  `timestamp` bigint(20) NOT NULL,   
  `data` text,   
  PRIMARY KEY (`breadcrumbs_id`,`users_id`),   
  KEY `fk_breadcrumbs_users1` (`users_id`)   
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=468792 ;   

android 设备以毫秒为单位发送时间戳,并遵循 UTC 时间标准来构建时间戳。我一直在尝试去除超过一个月的面包屑。由于 MySQL 没有毫秒格式,我一直在使用以下查询:

DELETE FROM breadcrumbs WHERE ((`timestamp`)/1000) < UNIX_TIMESTAMP() - 2592000;

删除记录需要相当长的时间。下面是运行删除查询的结果:

/*382,580 rows affected, 0 rows found. Duration for 1 query: 36.894 sec. */

我的问题是:

  1. 我是否正确拾取面包屑?
  2. 我可以优化DELETE查询,使其比当前运行得更快。
4

2 回答 2

3

选项 1:添加索引(timestamp)并测试此查询,以便可以使用索引:

DELETE FROM breadcrumbs 
WHERE `timestamp` < 1000 * UNIX_TIMESTAMP( NOW() - INTERVAL 1 MONTH ) ;

选项 2:使用@Micahel Berkowsi 的方法并存储部分时间戳,MySQL 无需转换即可使用。


选项 3:在MySQL 5.6发布时迁移到它(它仍处于 beta 测试阶段)或MariaDB 5.3 或 5.5,它们支持日期时间和时间戳列中的微秒精度

于 2012-11-13T13:33:18.570 回答
2

您的查询逻辑是正确的,但我建议不要首先存储毫秒格式,而是除以 1000 INSERT(或存储毫秒和普通 UNIX 时间戳格式)。或者,将其存储为DATETIME使用FROM_UNIXTIME(timestamp / 1000)时使用INSERT。然后,在列上创建索引timestamp,删除应该快得多。

CREATE TABLE IF NOT EXISTS `breadcrumbs` (   
  `breadcrumbs_id` bigint(20) NOT NULL AUTO_INCREMENT,   
  `users_id` int(10) NOT NULL, 
  `timestamp` bigint(20) NOT NULL,
  /* Also consider storing `timestamp` as a DATETIME */
  /* `timestamp` DATETIME NOT NULL, */
  `data` text,   
  PRIMARY KEY (`breadcrumbs_id`,`users_id`),
  KEY `fk_breadcrumbs_users1` (`users_id`),
  /* index on timestamp */
  INDEX `idx_timestamp` (`timestamp`) 
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=468792 ;   

/* Store the timestamp without the milliseconds (or store it both ways in 2 columns) */
INSERT INTO breadcrumbs (`breadcrumbs_id`, `users_id`, `timestamp`, `data`) VALUES (123,123, input_timestamp / 1000, data)
/* Or even better, store it as a MySQL DATETIME */
INSERT INTO breadcrumbs (`breadcrumbs_id`, `users_id`, `timestamp`, `data`) VALUES (123,123, FROM_UNIXTIME(input_timestamp / 1000), data)

作为索引DATETIME列,您的DELETE查询将如下所示:

DELETE FROM breadcrumbs WHERE `timestamp` < NOW() - INTERVAL 1 MONTH;
于 2012-11-13T13:30:48.113 回答