简体   繁体   English

非常慢的MYSQL子查询

[英]Very Slow MYSQL Sub Query

Guys, im more of a MSSQL guy but im working on some MYSQL right now. 伙计们,我更多的是一个MSSQL人,但我现在正在研究一些MYSQL。

Iv written a simple query, with a subquery and I cant understand for the life of me why its so slow. 我写了一个简单的查询,带有子查询,我无法理解为什么它的生命如此缓慢。

This query: 这个查询:

   SELECT MAX(timestamp), user, status FROM checkin WHERE room_id = 'Room Name' AND timestamp        > DATE_SUB(Now() ,INTERVAL 4005 SECOND) GROUP BY user

Runs in 0.0034 seconds 运行0.0034秒

Yet this relatively similiar query but nested, takes over 6 seconds .. 然而,这个相对类似的查询但是嵌套,需要6秒钟。

SELECT user, status FROM checkin
WHERE timestamp IN
(SELECT MAX(timestamp) FROM checkin WHERE room_id = 'Room Name' AND timestamp > DATE_SUB(Now() ,INTERVAL 4005 SECOND) GROUP BY user)

Can anyone please help? 有人可以帮忙吗? Im stuck. 我卡住了。

The table "checkin" only has about 900 rows in it. 表“checkin”中只有大约900行。 only the room_id column is indexed. 只有room_id列被编入索引。

Cheers 干杯

EDIT Thanks guys .. heres the result of the EXPLAIN 编辑谢谢你们...继承人探索的结果

DEPENDENT SUBQUERY checkin ref room_id room_id 202 const 1104 Using where; 相关的SUBQUERY checkin ref room_id room_id 202 const 1104使用where; Using temporary; 使用临时; Using filesort 使用filesort

Look into using a HAVING clause to achieve the same results. 考虑使用HAVING子句来实现相同的结果。 MySQL is notoriously bad at sub-query optimization, try this: MySQL在子查询优化方面非常糟糕,试试这个:

SELECT MAX(timestamp) as ts, user, status 
FROM checkin
WHERE room_id = 'Room Name' 
AND   timestamp > DATE_SUB(Now() ,INTERVAL 4005 SECOND)
GROUP BY user
HAVING timestamp = ts

also make sure that there is an index on timestamp 还要确保timestamp上有索引

Alternatively: 或者:

SELECT user, status 
FROM checkin
WHERE room_id = 'Room Name' 
AND   timestamp > DATE_SUB(Now() ,INTERVAL 4005 SECOND)
AND NOT EXISTS (SELECT * FROM checkin as newer 
                WHERE newer.timestamp>checkin.timestamp
                AND newer.room_id = 'Room Name'
                AND newer.user = checkin.user)
GROUP BY user

I think, that you are dealing with dependent subquery. 我想,你正在处理依赖子查询。 This means, that subquery is not executed once (as you and I would expect), but for every row - it is a known bug of MySQL. 这意味着,子查询不会执行一次(正如您和我所期望的那样),但对于每一行 - 它都是MySQL的已知错误。 If you can, split it into two queries - find out the MAX value first and then do a selection. 如果可以,将其拆分为两个查询 - 首先找出MAX值,然后进行选择。

Please run EXPLAIN on both queries. 请对两个查询运行EXPLAIN。 Propably you dont have proper indexes on your columns. 你的列上没有适当的索引。

Try that: 试试看:

EXPLAIN SELECT user, status FROM checkin WHERE timestamp IN (SELECT MAX(timestamp) FROM checkin WHERE room_id = 'Room Name' AND timestamp > DATE_SUB(Now() ,INTERVAL 4005 SECOND) GROUP BY user);

And: 和:

SELECT MAX(timestamp) FROM checkin WHERE room_id = 'Room Name' AND timestamp > DATE_SUB(Now() ,INTERVAL 4005 SECOND) GROUP BY user

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM