2012-07-19 78 views
0

我有什么看起来像一个简单的问题,但我挣扎。我有两个表格如下。比较缓慢的MySQL查询

表1有房事件和时间(秒) 表2有房访问时间(秒)和人

名称对于表1中的每一行我要输出的最后一个人进入房间,但只有当他们在最后5分钟进入房间

时间为两个表的表1(事件)

例如

|time  |event| 
|1294427839|poff | 
|1294427939|pofn | 
|1294428839|poff | 
主索引表

例子(项)

|time  |name| 
|1294427829|tpeters | 
|1294427929|jsmith | 
|1294428829|abeach | 

表1具有约5000行,表2约300000我目前使用下面的查询,但它正在采取分钟完成 。有人可能会提出我做错了什么。

select (SELECT name FROM entries entries WHERE entries.time > events.time-300 and entries.time < events.time order by entries.time desc limit 1) from events events 

任何帮助将不胜感激。

增加了更多的细节:

ID SELECT_TYPE  TABLE TYPE POSSIBLE_KEYS KEY  KEY_LEN  ROWS FILTERED EXTRA 
1 PRIMARY   events index     PRIMARY 8   3  100  Using index 
2 DEPENDENT SUBQUERY entries index PRIMARY   PRIMARY 8   1  300  Using where 

CREATE TABLE事件( time INT(11)NOT NULL DEFAULT '0', PRIMARY KEY(time) )ENGINE = InnoDB的默认字符集= UTF8 ROW_FORMAT = COMPACT ;

CREATE TABLE条目( time INT(11)NOT NULL DEFAULT '0', PRIMARY KEY(time) )ENGINE = InnoDB的默认字符集= UTF8 ROW_FORMAT = COMPACT;

+0

显示'EXPLAIN'和两个表的结构进行了测试。 PS:使用'INNER JOIN'重写查询 – zerkms 2012-07-19 22:24:59

回答

1

试试这个

SELECT name, ev_time, en_time 
FROM (
    SELECT 
    name, 
    IF(events.time = @last_time, 0, 1) AS last, 
    @last_time := events.time AS ev_time, 
    entries.time AS en_time 
    FROM events 
    LEFT JOIN entries ON (entries.time BETWEEN events.time-300 AND events.time) 
    ORDER BY events.time, entries.time 
) as tmp 
WHERE last = 1 

sqlfiddle

+0

非常感谢。有几个问题,首先我犯了一个错误,我的查询应该读取'order by entries.time',现在我已经在上面纠正 - sqlfiddle应该返回tpeters,jsmith,abeach。但其次,这看起来实际上并没有更快的执行速度,它仍然需要一分钟左右的时间,你会期待这个在我的大小的桌子上?它看起来很慢 – user1425395 2012-07-20 17:26:24

+0

因为你的解释说它在两种情况下都使用'PRIMARY',并且两者都是'index'类型,所以它不会变形,你可以按照原样优化它,如果你打算使用查询语句可能有助于向名为'closest_entry'的'events'添加一列,并在运行查询之前填充它,然后使用该列作为'equal_reference'离开'range' – 2012-07-20 18:42:07