2010-01-26 4 views
5

J'ai une requête joignant 4 tables avec beaucoup de conditions dans la clause WHERE. La requête inclut également la clause ORDER BY sur une colonne numérique. Il faut 6 secondes pour revenir, ce qui est trop long et je dois l'accélérer. Étonnamment, j'ai trouvé que si je supprime la clause ORDER BY cela prend 2 secondes. Pourquoi la commande fait tellement de différence et comment l'optimiser? J'utilise SQL Server 2005. Merci beaucoup.Mauvaise performance de requête SQL en raison de la clause ORDER BY

Je ne peux pas confirmer que ORDER BY fait une grande différence puisque j'efface le cache du plan d'exécution. Cependant pouvez-vous faire la lumière sur la façon d'accélérer un peu? La requête est la suivante (pour simplifier, il y a "SELECT *" mais je ne sélectionne que ceux dont j'ai besoin).

SELECT * 
FROM View_Product_Joined j 
INNER JOIN [dbo].[OPR_PriceLookup] pl on pl.siteID = NodeSiteID and pl.skuid = j.skuid 
LEFT JOIN [dbo].[OPR_InventoryRules] irp on irp.ID = pl.SkuID and irp.InventoryRulesType = 'Product' 
LEFT JOIN [dbo].[OPR_InventoryRules] irs on irs.ID = pl.siteID and irs.InventoryRulesType = 'Store' 
WHERE (((((SiteName = N'EcommerceSite') AND (Published = 1)) AND (DocumentCulture = N'en-GB')) AND (NodeAliasPath LIKE N'/Products/Cats/Computers/Computer-servers/%')) AND ((NodeSKUID IS NOT NULL) AND (SKUEnabled = 1) AND pl.PriceLookupID in (select TOP 1 PriceLookupID from OPR_PriceLookup pl2 where pl.skuid = pl2.skuid and (pl2.RoleID = -1 or pl2.RoleId = 13) order by pl2.RoleID desc))) 
ORDER BY NodeOrder ASC 
+3

Avez-vous regardé le plan de requête? –

+3

essayez d'indexer la colonne que vous utilisez dans votre clause ORDER BY (si ce n'est pas déjà fait) – davek

+2

Assurez-vous également d'effacer le cache de plan de données/d'exécution entre chaque test, sinon vous pourriez obtenir des résultats faussés (pire scénario de cas est qu'ils exécutent effectivement la même chose, mais le 2e s'exécute plus rapidement car il obtient des données à partir du cache). – AdaTheDev

Répondre

6

Pourquoi l'ordre par fait la différence si massive et comment l'optimiser?

Le ORDER BY doit trier le jeu de résultats, ce qui peut prendre du temps s'il est important.

Pour l'optimiser, vous devrez peut-être indexer correctement les tables. Cependant, le chemin d'accès à l'index a ses inconvénients, ce qui peut même prendre plus de temps.

Si vous avez quelque chose autre que équijointures dans votre requête, ou les prédicats (comme < à distance, ou >BETWEEN, ou GROUP BY clause), l'indice utilisé pour ORDER BY peut empêcher les autres indices soient utilisés.

Si vous publiez la requête, je serai probablement en mesure de vous dire comment l'optimiser.

Mise à jour:

Réécrivez la requête:

SELECT * 
FROM View_Product_Joined j 
LEFT JOIN 
     [dbo].[OPR_InventoryRules] irp 
ON  irp.ID = j.skuid 
     AND irp.InventoryRulesType = 'Product' 
LEFT JOIN 
     [dbo].[OPR_InventoryRules] irs 
ON  irs.ID = j.NodeSiteID 
     AND irs.InventoryRulesType = 'Store' 
CROSS APPLY 
     (
     SELECT TOP 1 * 
     FROM OPR_PriceLookup pl 
     WHERE pl.siteID = j.NodeSiteID 
       AND pl.skuid = j.skuid 
       AND pl.RoleID IN (-1, 13) 
     ORDER BY 
       pl.RoleID desc 
     ) pl 
WHERE SiteName = N'EcommerceSite' 
     AND Published = 1 
     AND DocumentCulture = N'en-GB' 
     AND NodeAliasPath LIKE N'/Products/Cats/Computers/Computer-servers/%' 
     AND NodeSKUID IS NOT NULL 
     AND SKUEnabled = 1 
ORDER BY 
     NodeOrder ASC 

La relation View_Product_Joined, comme son nom l'indique, est probablement une vue.

Pourriez-vous s'il vous plaît poster sa définition?

S'il est indexable, vous pouvez bénéficier de la création d'un index sur View_Product_Joined (SiteName, Published, DocumentCulture, SKUEnabled, NodeOrder).

+0

Requête postée ... – David

+0

Afin d'exécuter la requête, j'ai dû ajouter skuID et siteID en sortie de la requête cross apply, et lui donner un nom d'alias.Il est maintenant beaucoup plus rapide mais renvoie également environ 40% des enregistrements. Devra enquêter plus loin. – David

+0

'@ David': J'ai corrigé la requête un peu, s'il vous plaît voir la mise à jour post. Est-ce que 'PriceLookupID' est' PRIMARY KEY' sur 'OPR_PriceLookup'? – Quassnoi