0

我有一张看起来像这样的表:

ID | objectID | time | ...
-------------------
 1 |        1 | ...
 2 |        1 | ...
 3 |        1 | ...
 4 |        2 | ...
 5 |        2 | ...
 6 |        3 | ...
 7 |        4 | ...

ID 是主键,objectID 是非唯一的。我正在尝试提高查询的性能以获取所有 objectID 的最新条目,但这些条目不应比某个值新。我尝试遵循两个查询,它们都应该提供相同的(和正确的结果):

SELECT *
FROM (
    SELECT *
    FROM table
    WHERE time <= XXX
    ORDER BY time DESC
)
GROUP BY objectID

SELECT *
FROM table AS t     
INNER JOIN (
    SELECT ID, MAX(time)
    FROM table
    WHERE time <= 1353143351
    GROUP BY objectID
) s
USING (ID)

第一个查询的解释告诉我

id | select_type | table      | type | possible_keys | key     | key_len | ref  | rows   | Extra
------------------------------------------------------------------------------------
1  | PRIMARY     | <derived2> | ALL  | NULL          | NULL    | NULL    | NULL | 145827 | Using temporary; Using filesort
2  | DERIVED     | tbl_test   | ALL  | NULL          | NULL    | NULL    | NULL | 238694 | Using filesort

对于第二个查询,它说

id | select_type | table      | type   | possible_keys | key     | key_len | ref  | rows   | Extra
------------------------------------------------------------------------------------
1  | PRIMARY     | <derived2> | ALL    | NULL          | NULL    | NULL    | NULL | 325 
1  | PRIMARY     | t          | eq_ref | PRIMARY,ID    | PRIMARY | 4       | s.ID | 1   
2  | DERIVED     | tbl_test   | index  | NULL          | ID      | 12      | NULL | 238694 | Using where; Using index; Using temporary; Using filesort

(tbl_test 是我的测试表)

第二个查询似乎(快得多),但仍然不是非常快,运行时间为 0.1 秒,大约 200k 数据库条目。有没有办法提高查询的性能?有没有缺失的索引?

提前致谢!!

编辑:解释 eggys 查询(参见他的帖子中的查询):

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY <derived2>  ALL NULL    NULL    NULL    NULL    325 
1   PRIMARY lab_case_test   ALL NULL    NULL    NULL    NULL    238694  Using where; Using join buffer
2   DERIVED lab_case_test   index   NULL    ID  12  NULL    238694  Using where; Using index; Using temporary; Using f...

CREATE TABLE `lab_case_test` (
 `ID` int(11) NOT NULL AUTO_INCREMENT,
 `caseID` int(11) NOT NULL,
 `time` int(11) NOT NULL,
 // ....
 PRIMARY KEY (`ID`),
 KEY `ID` (`ID`,`caseID`,`time`),
 KEY `caseID` (`caseID`,`time`)
) ENGINE=MyISAM AUTO_INCREMENT=238695 DEFAULT CHARSET=utf8
4

1 回答 1

1

您想要一个复合索引(objectID, time)

ALTER TABLE my_table ADD INDEX (objectID, time)

这样做的原因是 MySQL 可以直接从索引树中检索time每个的最大值;objectID然后,它还可以使用相同的索引再次加入表中,以使用类似于第二个查询的方式查找分组最大objectID记录(但应该同时加入两者,并且time- 我喜欢NATURAL JOIN在这种情况下使用 a ):

SELECT *
FROM   my_table NATURAL JOIN (
  SELECT   objectID, MAX(time) time
  FROM     my_table
  WHERE    time <= 1353143351
  GROUP BY objectID
) t
于 2013-03-28T19:16:55.860 回答