Очень медленный MYSQL подзапрос - PullRequest
3 голосов
/ 11 мая 2011

Ребята, я скорее парень из MSSQL, но сейчас я работаю над некоторым MYSQL.

Я написал простой запрос с подзапросом, и я не могу понять, почему он такой медленный.1003 *

Этот запрос:

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

Запускается за 0,0034 секунды

Тем не менее этот относительно похожий запрос, но вложенный, занимает более 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)

Может кто-нибудь, пожалуйста, помогите?Я застрял.

В таблице "checkin" всего около 900 строк.индексируется только столбец room_id.

Приветствия

РЕДАКТИРОВАТЬ Спасибо, ребята .. Вот результат ОБЪЯСНЕНИЯ

ЗАВИСИТ ОТ ПОДПИСКИ ref_ номер_ид 20_2const 1104 Использование где;Используя временные;Использование файловой сортировки

Ответы [ 3 ]

4 голосов
/ 11 мая 2011

Обдумайте использование предложения HAVING для достижения тех же результатов. 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

также убедитесь, что на timestamp

есть индекс

В качестве альтернативы:

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
2 голосов
/ 11 мая 2011

Я думаю, что вы имеете дело с зависимым подзапросом.Это означает, что подзапрос не выполняется один раз (как вы и я ожидали), но для каждой строки - это известная ошибка MySQL.Если вы можете, разделите его на два запроса - сначала найдите значение MAX, а затем сделайте выбор.

1 голос
/ 11 мая 2011

Пожалуйста, запустите EXPLAIN для обоих запросов.Вероятно, у вас нет подходящих индексов для ваших столбцов.

Попробуйте:

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);

И:

SELECT MAX(timestamp) FROM checkin WHERE room_id = 'Room Name' AND timestamp > DATE_SUB(Now() ,INTERVAL 4005 SECOND) GROUP BY user
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...