2010-03-04 3 views
2

У меня есть запрос с подзапросом, но таблица подзапроса содержит около 500 000 записей, и выполнение этого запроса занимает слишком много времени. Как я могу ускорить этот запрос? Любые предложения:Ошибка производительности сортировки MySQL

SELECT ID, VehicleID, Plate, VehicleType, 
    COALESCE(
     (SELECT EngineState 
     FROM Locations 
     WHERE Locations.VehicleID = Clients.VehicleID ORDER BY ID DESC LIMIT 1), 
     0 
    ) EngineState 
FROM Clients 
WHERE ID IN (SELECT ClientID FROM UserClients WHERE [email protected]); 

Там еще 3 колонки, которые запрашивают последнюю запись из таблицы Locations:

COALESCE(
    (SELECT EngineState FROM Locations 
    WHERE Locations.VehicleID = Clients.VehicleID ORDER BY ID DESC LIMIT 1), 
    0 
) EngineState 

Как я вижу сортировки результатов в таблице Locations является фактором производительности там. Таблица мест, если каждую минуту заполняется данными о местонахождении 1000 автомобилей. х, у, скорость ...

ответ

1

Индексы необходимы на всех колонках, используемых в соединениях плюс Идентификатор_пользователя в UserClient

Запросы, сделанные на Select замедляются время выполнения много.
Следующий запрос повысит производительность.

SELECT c.ID, c.VehicleID, c.Plate, c.VehicleType, 
IFNULL(l.enginestate, 0) AS enginestate 
FROM Clients c 
JOIN (
    SELECT MAX(ID) AS ID, vehicleID 
    FROM Locations 
    GROUP BY vehicleID 
) ll 
    ON ll.VehicleID = c.VehicleID 
JOIN Locations l 
    ON ll.ID = l.ID 
JOIN UserClients uc 
    ON uc.clientID = c.ID 
WHERE [email protected] 

Также я предпочитаю IFNULL to COALESCE при получении только одного значения поля.

3

Создать следующие показатели:

Locations (vehicleId, id) 
UserClients (UserID, ClientID) 

и переписать запрос немного:

SELECT ID, VehicleID, Plate, VehicleType, l.* 
FROM Clients 
LEFT JOIN 
     Locations l 
ON  l.id = 
     (
     SELECT id 
     FROM Locations li 
     WHERE li.VehicleID = Clients.VehicleID 
     ORDER BY 
       li.VehicleID DESC, li.id DESC 
     LIMIT 1 
     ) 
WHERE Clients.ID IN 
     (
     SELECT ClientID 
     FROM UserClients 
     WHERE UserID = @UserID 
     ) 

Поскольку ваша VehicleID является VARCHAR(64), вы должны убедиться, что Clients.VehicleID и Locations.VehicleID использовать тот же набор символов и одинаковый сопоставление.

+0

Могу ли я проиндексировать поле varchar (64)? Потому что VehicleID является VarChar (64) ... –

+0

@ Хасан: почему, вы можете. – Quassnoi

+0

Также Locations table engine - MyISAM ..? –

Смежные вопросы