在表'ttraces'中,我有许多不同任务的记录(其值保存在'taskid'列中,并且是表'ttasks'中列'id'的外键)。每个任务每8-10秒插入一条“ttraces”记录,因此缓存数据以提高性能并不是一个好主意。我需要的是从'ttraces'中仅选择每个任务的最新记录,这意味着具有“时间”列的最大值的记录。目前,我在表中有超过500000条记录。这两个表的非常简化的结构如下所示:
-----------------------
| ttasks |
-----------------------
| id | name | blocked |
-----------------------
---------------------
| ttraces |
---------------------
| id | taskid | time |
---------------------
我的查询如下所示:
SELECT t.name,tr.time
FROM
ttraces tr
JOIN
ttasks t ON tr.itask = t.id
JOIN (
SELECT taskid, MAX(time) AS max_time
FROM ttraces
GROUP BY itask
) x ON tr.taskid = x.taskid AND tr.time = x.max_time
WHERE t.blocked
WHERE和JOIN子句中使用的所有列都已编制索引。至于现在,查询运行约1.5秒。提高速度至关重要。谢谢你的所有建议。顺便说一句:数据库在托管的共享服务器上运行,暂时我无法将其移动到其他任何地方。
[编辑] EXPLAIN SELECT ...结果是:
--------------------------------------------------------------------------------------------------------------
id select_type table type possible_keys key key_len ref rows Extra
--------------------------------------------------------------------------------------------------------------
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 74
1 PRIMARY t eq_ref PRIMARY PRIMARY 4 x.taskid 1 Using where
1 PRIMARY tr ref taskid,time time 9 x.max_time 1 Using where
2 DERIVED ttraces index NULL itask 5 NULL 570853
--------------------------------------------------------------------------------------------------------------
引擎是InnoDB。
答案 0 :(得分:1)
我可能会有一点时间,但这个查询在逻辑上是不一样的,而且(几乎可以肯定)更快?
SELECT t.id, t.name,max(tr.time)
FROM
ttraces tr
JOIN
ttasks t ON tr.itask = t.id
where BLOCKED
group by t.id, t.name
答案 1 :(得分:0)
如果每个任务有很多跟踪,那么您可以保留一个只包含最新跟踪的表。每当你插入ttraces时,你也会插入ttraces_newest:
insert into ttraces_newest (id, taskid, time) values
(3, 1, '2012-01-01 08:02:01')
on duplicate key update
`time` = current_timestamp
ttraces_newest的主键是(id,taskid)。查询ttraces_newest会更便宜。便宜多少取决于每项任务有多少痕迹。现在查询是:
SELECT t.name,tr.time
FROM
ttraces_newest tr
JOIN
ttasks t ON tr.itask = t.id
WHERE t.blocked
答案 2 :(得分:0)
这是我的想法......您需要ttraces
上有taskid
和time
列的一个综合索引(按此顺序)。比,使用此查询:
SELECT t.name,
trm.mtime
FROM ttasks AS t
JOIN (SELECT taskid,
Max(time) AS mtime
FROM ttraces
GROUP BY taskid) AS trm
ON t.id = trm.taskid
WHERE t.blocked
答案 3 :(得分:0)
此代码是否返回正确的结果?如果是这样,它的速度时间如何?
SELECT t.name, max_time
FROM ttasks t JOIN (
SELECT taskid, MAX(time) AS max_time
FROM ttraces
GROUP BY taskid
) x ON t.id = x.taskid