我在 Linux (RHEL) 上使用 MySQL 5.6。数据库客户端是一个 Java 程序。有问题的表(MyISAM 或 InnoDB,两者都尝试过)有一个多列索引,包括两个整数(来自其他表的 id)和一个时间戳。
我想删除在给定日期之前具有时间戳的记录。我发现此操作相对较慢(在具有几百万条记录的表中大约需要 30 秒)。但是我也发现,如果指定索引中的另外两个字段,操作会快很多。那里没有什么大惊喜。
我相信我可以查询两个非时间戳表的索引值,然后循环删除操作,每次指定每个 id 的一个值。我希望这不会花太长时间;我还没试过。但似乎我应该能够让 MySQL 为我做循环。我尝试了表单的查询
delete from mytable where timestamp < '2013-08-17'
    and index1 in (select id from foo)
    and index2 in (select id from bar);
但这实际上比
delete from mytable where timestamp < '2013-08-17';
两个问题。(1)我可以做些什么来加快仅依赖于时间戳的删除操作?(2) 如果做不到这一点,我可以做些什么来让 MySQL 循环遍历另外两个索引列(并快速完成)?
实际上,我对具有相同数据的 MyISAM 和 InnoDB 表都尝试了此操作——它们的速度大致相同。
提前感谢您对这个问题的任何了解。
编辑:有关表结构的更多信息。这是输出show create table mytable:
CREATE TABLE `mytable` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `timestamp` datetime NOT NULL,
  `fooId` int(10) unsigned NOT NULL,
  `barId` int(10) unsigned NOT NULL,
  `baz` double DEFAULT NULL,
  `quux` varchar(16) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `fooId` (`fooId`,`barId`,`timestamp`)
) ENGINE=InnoDB AUTO_INCREMENT=14221944 DEFAULT CHARSET=latin1 COMMENT='stuff'
这是输出show indexes from mytable:
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
|mytable|          0 | PRIMARY  |            1 | id          | A         |     2612681 |     NULL | NULL   |      | BTREE      |         |               |
|mytable|          0 | fooId    |            1 | fooId       | A         |          20 |     NULL | NULL   |      | BTREE      |         |               |
|mytable|          0 | fooId    |            2 | barId       | A         |        3294 |     NULL | NULL   |      | BTREE      |         |               |
|mytable|          0 | fooId    |            3 | timestamp   | A         |     2612681 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
编辑:更多信息——“解释”的输出。
mysql> explain delete from mytable using mytable inner join foo inner join bar where mytable.fooId=foo.id and mytable.barId=bar.id and timestamp<'2012-08-27';
+----+-------------+-------+-------+---------------+---------+---------+-------------------------------+------+----------------------------------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref                           | rows | Extra                                              |
+----+-------------+-------+-------+---------------+---------+---------+-------------------------------+------+----------------------------------------------------+
|  1 | SIMPLE      | foo   | index | PRIMARY       | name    | 257     | NULL                          |   26 | Using index                                        |
|  1 | SIMPLE      | bar   | index | PRIMARY       | name    | 257     | NULL                          |   38 | Using index; Using join buffer (Block Nested Loop) |
|  1 | SIMPLE      |mytable| ref   | fooId         | fooId   | 8       | foo.foo.id,foo.bar.id         |  211 | Using where                                        |
+----+-------------+-------+-------+---------------+---------+---------+-------------------------------+------+----------------------------------------------------+