3

我有一个存储在 mysql 中的大表(基本上是一个日志),如下所示:

  CREATE TABLE `log` (
    `ID_1` int(10) unsigned NOT NULL,
    `ID_2` int(10) unsigned NOT NULL,
    `DELTA` tinyint(3) unsigned NOT NULL,
    `ACTIVE` tinyint(1) NOT NULL,
    `DATA` bigint(20) unsigned NOT NULL,
  ) ENGINE=MyISAM DEFAULT CHARSET=utf8$$

没有索引。数据是在随机时刻插入随机数据的,并且工作正常。然后,表脱机(没有读/写操作)。此时的表大小约为 180M 记录。我在 ID_1、ID_2、DELTA、ACTIVE 字段(全部 4 个,升序)上添加索引。它的工作速度相当快(3-4 分钟)。

现在,我正在尝试按 ID_1、ID_2、DELTA、ACTIVE(与索引相同的字段和相同的顺序)按升序从表中获取所有数据,但选择在“排序结果”中保留了很长时间(在 SHOW PROCESSLIST) 直到返回第一行。我试图提示/强制 SELECT 语句使用索引(即 FORCE INDEX / USE INDEX),但没有任何区别。关于如何提高此类查询的响应速度的任何提示:

SELECT `ID_1`, `ID_2`, `DELTA`, `ACTIVE` FROM `log` ORDER BY `ID_1`, `ID_2`, `DELTA`, `ACTIVE` ASC;

?

在这里提出了一个类似的问题:Slow ORDER BY in large table - 但没有答案。认为发布一个喜欢它是个好主意,也许现在有人知道答案了。

谢谢!

4

1 回答 1

7

为了有效地对数据进行排序,您必须使用要在ORDER BY子句中使用的所有列添加复合索引。索引中列的顺序必须与ORDER BY子句中的列顺序相同。

在您的情况下,它将是:

ALTER TABLE `log` ADD INDEX mySortIndex(`ID_1`, `ID_2`, `DELTA`, `ACTIVE`);

要检查 MySQL 如何执行您的查询,请使用:

EXPLAIN SELECT `ID_1`, `ID_2`, `DELTA`, `ACTIVE` FROM `log` ORDER BY `ID_1`, `ID_2`, `DELTA`, `ACTIVE` ASC;

输出将告诉您使用了哪些索引。

如果您只需要已知数量的结果行,您可以使用LIMIT来阻止 MySQL 对整个表进行排序:

SELECT `ID_1`, `ID_2`, `DELTA`, `ACTIVE`
FROM `log` ORDER BY `ID_1`, `ID_2`, `DELTA`, `ACTIVE` ASC
LIMIT 100;
于 2012-11-15T01:32:24.640 回答