2012-07-19 135 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