2009-08-28 4 views
1

J'utilise le TOAD de Quest pour SQL Server sur un serveur SQL Server 2000.Optimisation de requête - Pourquoi cela accélère-t-il la requête?

Voici ma question:

SELECT CASE SLCE.GroupName WHEN 'Other' THEN ARM.FBCOMPANY 
          WHEN 'Inter Co.' THEN ARM.FBCOMPANY 
          ELSE SLCE.GroupName END AS [Company Name], 
     ARM.fcustno AS [Cust No], 
     ARM.fbcompany AS [Cust Name], 
     ARM.fcinvoice AS [Invoice No], 
     ARM.fdgldate AS [Post Date], 
     year(arm.fdgldate) AS [Year Posted], 
     CASE ARM.fcsource WHEN 'S' THEN 'Shipper' 
         WHEN 'O' THEN 'Sales Order' 
         WHEN 'R' THEN 'Receiver' 
         WHEN 'C' THEN 'Customer' 
         ELSE ARM.fcsource END AS [Source Doc Type], 
     CASE ARM.fcstatus WHEN 'N' THEN 'New' 
         WHEN 'U' THEN 'Unpaid' 
         WHEN 'P' THEN 'Partially Paid' 
         WHEN 'F' THEN 'Paid in Full' 
         WHEN 'H' THEN 'Held' 
         WHEN 'V' THEN 'Voided' 
         ELSE ARM.fcstatus END AS [Invoice Status], 
     ARM.fpono AS [Cust PO No], 
     ARM.fsalespn AS [Sales Person], 
     ARI.fitem AS [Item No], 
     ARI.fprodcl AS [Prod Class], 
     ARI.fshipkey AS [Qty Invoiced], 
     ARI.ftotprice AS [Net Invoiced], 
     ARI.fpartno AS [Part No], 
     ARI.frev AS [Part Rev], 
     cast(ARI.fmdescript AS VARCHAR(20)) AS [Part Description], 
     ARM.fsono AS [Sales No], 
     ARI.fsokey AS [SO Rels Key], 
     ARI.fordqty AS [Qty Ordered], 
     RED.[YEAR] AS [Year], 
     RED.PERIOD AS [RF Period] 
    FROM dbo.armast ARM 
     INNER JOIN dbo.aritem ARI 
      ON ARM.FCINVOICE = ARI.FCINVOICE 
     INNER JOIN slcdpm SLC 
      ON SLC.fcustno = ARM.fcustno 
     LEFT OUTER JOIN slcdpm_ext SLCE 
     ON SLC.identity_column = SLCE.fkey_id 
     INNER JOIN REDFRIDAYDATES..TBLREDFRIDAYALLDATES RED 
      ON RED.date = CAST (FLOOR (CAST (ARM.fdgldate AS FLOAT)) AS DATETIME) 
WHERE ARM.fcstatus <> 'V' 
    AND RED.[YEAR] = year(getdate()) 
    AND ari.frev = 'REP' 
    AND ARI.fsalesacc IN ('4010001', '4010002', '4010003', '4010004', '4010005', '4010006', '4010007', '4010008', '4010009', '4010010', '4010018', '4010019', '4010020', '4010021', '4010031', '4010050', '4022000', '4031000', '4045000', '4055000', '4057000', '4060000', '4070000') 

Voici l'option de TOAD (avec des différences mises en évidence) est la suivante:

INNER JOIN dbo.aritem ARI 
      ON ARM.FCINVOICE = ***COALESCE (ARI.FCINVOICE , ARI.FCINVOICE)*** 
     INNER JOIN slcdpm SLC 
      ON SLC.fcustno = ARM.fcustno 
     LEFT OUTER JOIN slcdpm_ext SLCE 
     ON SLC.identity_column = SLCE.fkey_id 
     INNER JOIN REDFRIDAYDATES..TBLREDFRIDAYALLDATES RED 
      ON RED.date = CAST (FLOOR (CAST (ARM.fdgldate AS FLOAT)) AS DATETIME) 
WHERE ARM.fcstatus <> 'V' 
    AND RED.[YEAR] = year(getdate()) 
    AND ari.frev = 'REP' 
    AND ARI.fsalesacc IN ('4010001', '4010002', '4010003', '4010004', '4010005', '4010006', '4010007', '4010008', '4010009', '4010010', '4010018', '4010019', '4010020', '4010021', '4010031', '4010050', '4022000', '4031000', '4045000', '4055000', '4057000', '4060000', '4070000') 
    ***AND ARI.[fpartno] >= CHAR(0)*** 

Quelqu'un peut-il s'il vous plaît me dire pourquoi soudent et vitesse supplémentaire et déclaration cette requête de plus de 50%?

Répondre

3

Avez-vous regardé les plans d'exécution réels. Ceux-ci devraient vous montrer les différentes approches que SQL Server a prises dans l'exécution de ces requêtes.

1

C'est vraiment étrange. Le plan d'exécution devrait vous le dire avec certitude, mais les changements de performance de ce type dans les bases de données se résument presque toujours à un index. Donc, ma meilleure estimation est que SQL Server manquait d'un index qu'il pourrait utiliser et l'ajout de ces changements impairs fait ressortir mieux.

Mais si vous cherchez à apprendre le «pourquoi» impliqué afin que la prochaine fois que vous pouvez écrire votre requête pour être plus rapide en premier lieu, il n'y a vraiment rien là.

1

Une WAG complète:

Je vais deviner que fpartno a une condition « non nulle » sur elle (si le filtre ajouté passe toujours), et que le crapaud arrive à savoir que SQLServer est pas assez intelligent pour détecter que> = CHAR (0) est toujours vrai. Cela suggère donc que Toad essaie de guider, de façon très oblique, l'optimiseur pour utiliser quelque chose qui a du fparto. Que quelque chose pourrait être un indice composite sur (fcinvoice, fpartno) .. en avez-vous un?

Comme les autres l'ont dit, le plan d'explication devrait s'avérer utile pour expliquer le mystère.

1

Aucune de ces changements ont un effet sur la signification logique de la requête (ils sont « non ops »)

Le seul effet physique que COALESCE sur la clause ON serait d'empêcher l'optimiseur de essayer d'utiliser un index pour ARI.FCINVOICE. De même, le seul effet physique que le "> = CHAR (0)" pourrait avoir sur l'optimiseur pourrait être de le pousser à envisager d'utiliser un balayage de plage indexée (ou également une recherche) sur un index qui avait ARI. [Fpartno] dedans. Donc, ma conclusion serait que TOAD essaye de manipuler l'optimiseur en utilisant un index particulier sans réellement forçant à utiliser cet index avec un indice HINT explicite. En fait, c'est assez intelligent car le vrai problème avec les conseils de l'optimiseur T-SQL est leurs dépendances et leur fragilité.

Questions connexes