2010-03-04 4 views
2

J'ai une requête avec sous-requête mais la table de sous-requêtes a environ 500.000 enregistrements et l'exécution de cette requête prend trop de temps. Comment puis-je accélérer cette requête? Toutes les suggestions:Problème de performance de tri 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]); 

Il y a 3 autres colonnes qui questionnent le dernier enregistrement de la table Emplacements:

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

Comme je vois trier les résultats dans le tableau des emplacements est le facteur de performance là-bas. Tableau des emplacements si rempli toutes les minutes par 1000 données de localisation des véhicules. x, y, vitesse ...

Répondre

1

Les index sont nécessaires sur toutes les colonnes utilisées dans JOIN, plus UserID dans UserClient

requêtes effectuées sur Select ralentissent le temps d'exécution beaucoup.
La requête suivante améliorerait les performances.

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] 

Je préfère également IFNULL à COALESCE lorsque j'obtiens une seule valeur de champ.

3

Créer les indices suivants:

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

et réécrire votre requête un peu:

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 
     ) 

Depuis votre VehicleID est un VARCHAR(64), vous devez vous assurer que Clients.VehicleID et Locations.VehicleID utilisent le même jeu de caractères et le même classement.

+0

Puis-je indexer le champ varchar (64)? Parce que VehicleID est VarChar (64) ... –

+0

@Hasan: pourquoi, vous pouvez. – Quassnoi

+0

Le moteur de table Emplacements est également MyISAM ..? –