2011-05-09 4 views
0

J'ai la requête SQL suivante (assez ancienne, il y a un an ou deux). La page Web sur laquelle le SQL est activé (utilisée sur un SqlDataSource/GridView dans ASP.NET) est très lente, et j'ai identifié la lenteur de cette requête - apparemment à cause du sous-select. J'ai essayé d'utiliser des jointures pour l'accélérer, mais je n'arrive pas à le faire fonctionner. Des idées?Accélérer cette requête SQL

Je ne mettrai pas toute la requête ici, simplement parce que je travaille sur une machine sans accès à Internet, donc je ne serai pas capable de copier et coller, et la plupart ne fait que sélectionner dans la table principale.

SELECT ..., 
     CASE 
     WHEN di.Total = di.Delivered THEN 'Received' 
     ELSE 'Not Received' END AS 'Status', 
     ... 
FROM Deliveries AS d 
    LEFT OUTER JOIN (
     SELECT Delivery, 
       COUNT(*) AS Total, 
       COUNT(CASE WHEN Status = 2 THEN 1 END) AS Delivered 
     FROM DeliveryItems 
     GROUP BY Delivery 
) AS di ON d.ID = di.Delivery 

Des conseils?

+4

Pouvez-vous ajouter le plan d'exécution à partir de l'Analyseur de requêtes? Cela vous indique généralement quelle étape cause le ralentissement. – Keith

+2

Vous avez des index corrects sur DeliveryItems.Delivery et Deliveries.ID? – spender

+0

Retagged - le contenu d'ASP.Net n'est pas pertinent, c'est du SQL pur – RichardW1001

Répondre

0
SELECT Delivery, 
     COUNT(*) AS Total, 
     COUNT(CASE WHEN Status = 2 THEN 1 END) AS Delivered 
FROM DeliveryItems 
GROUP BY Delivery 

Cette partie pourrait être améliorée en abandonnant cette instruction CASE. Peut-être essayer de rejoindre deux fois, une fois contre le nombre total et une fois contre le compte filtré.

SELECT ..., 
     CASE 
     WHEN d2.Total = d1.Delivered THEN 'Received' 
     ELSE 'Not Received' END AS 'Status', 
     ... 
FROM Deliveries AS d 

LEFT OUTER JOIN (

SELECT Delivery, 
     COUNT(*) AS Delivered 
FROM DeliveryItems 
WHERE Status = 2 
GROUP BY Delivery) d1 ON d.Id = d1.Delivery 

LEFT OUTER JOIN (

SELECT Delivery, 
     COUNT(*) AS Total 
FROM DeliveryItems 
GROUP BY Delivery) d2 ON d.ID = d2.Delivery