mysql索引似乎在大表中失败了

时间:2013-01-25 11:04:53

标签: mysql indexing timestamp

我使用了一个大型(> 1亿行)表,其中包含以下内容:

 data_values | CREATE TABLE `data_values` (
  `T` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `ID` varchar(32) NOT NULL,
  `VAL` float DEFAULT NULL,
  PRIMARY KEY (`T`,`ID`),
  KEY `IX_d` (`ID`),
  KEY `IX_T` (`T`)
) ENGINE=InnoDB DEFAULT CHARSET=greek PACK_KEYS=1 ROW_FORMAT=DYNAMIC |

我的查询格式如下:

select t,id,val from data_values where t between "2013-01-11 02:47:02" and "2013-01-12 04:59:02" and id="815";

我的问题是有时使用索引(答案非常快),有时它没有被使用(答案是1-2分钟),我找不到任何逻辑。例如,以下查询很快:

select t,id,val from data_values where t between "2013-01-11 02:47:02" and "2013-01-13 04:59:02" and id="815";

虽然以下查询(要求少一些数据,一天而不是两天)很慢:

select t,id,val from data_values where t between "2013-01-11 02:47:02" and "2013-01-12 04:59:02" and id="815";

解释查询:

explain select t,id,value from data_values where t between "2013-01-11 02:47:02" and "2013-01-13 04:59:02" and id="815";
| id | select_type | table                | type        | possible_keys
| key             | key_len | ref  | rows | Extra
          |
+----+-------------+----------------------+-------------+-----------------------
+-----------------+---------+------+------+-------------------------------------
----------+
|  1 | SIMPLE      | data_values           | index_merge | PRIMARY,IX_D,IX_T
| IX_D,PRIMARY     | 34,38  | NULL | 1033 | Using intersect(IX_D,PRIMARY); Us
ing where |
+----+-------------+----------------------+-------------+-----------------------
+-----------------+---------+------+------+-------------------------------------


explain select t,id,val from data_values where t between "2013-01-11 02:47:02" and "2013-01-12 04:59:02" and id="815";
+----+-------------+----------------------+------+-----------------------+------
---+---------+-------+--------+-------------+
| id | select_type | table                | type | possible_keys         | key
   | key_len | ref   | rows   | Extra       |
+----+-------------+----------------------+------+-----------------------+------
---+---------+-------+--------+-------------+
|  1 | SIMPLE      | data_values          | ref  | PRIMARY,IX_D,IX_T     | IX_D            | 34      | const | 143900 | Using where |
+----+-------------+----------------------+------+-----------------------+------
---+---------+-------+--------+-------------+

我不明白第一个查询是“更广泛”(要求更多数据)如何使用索引而第二个查询不是。搜索stackoverflow我找到了一些关于多列索引的答案。但我已经使用了一个(我的主键),并且按正确的顺序(在查询中,在id之前提到了t变量)。我发现的另一个答案是关于OR的查询(单独查询并形成UNION),但我的查询使用AND。

我需要有关如何加快查询速度的建议,

非常感谢。

1 个答案:

答案 0 :(得分:0)

您有(t, id)的索引。

对于此类查询,您需要(id, t)上的索引,甚至更好,(id, t, val)上的“覆盖”索引:

ALTER TABLE data_values
    DROP INDEX IX_T           -- the Primary Key is (t, id) so this index 
                              -- is rather redundant.
  , DROP INDEX IX_d           -- this was not redundant but it is now
                              -- (because of) 
  , ADD INDEX IX_ID_T_VAL     -- the new index
        (id, t, value) ;