Question

J'utilise le TOAD de Quest for SQL Server sur un SQL Server 2000 Server.

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 en surbrillance) est:

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 et qui soudent accélérer cette requête de plus de 50% supplémentaires et déclaration?

Était-ce utile?

La solution

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

Autres conseils

Il est certainement un intrus. Le plan d'exécution devrait vous dire avec certitude, mais les changements de performance comme celle-ci dans les bases de données presque toujours baissé à un indice. Donc, ma meilleure estimation est que le serveur en quelque sorte sql il manquait un indice qu'il pourrait utiliser et l'ajout de ces changements bizarres fait ressortir mieux.

Mais si vous cherchez à apprendre le « pourquoi » impliqués 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.

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> = CHAR (0) est toujours vrai. Donc, cela suggère que le crapaud tente de guider, d'une manière très oblique, l'optimiseur d'utiliser quelque chose qui a fpartno en elle. Que quelque chose pourrait être un indice composite sur (fcinvoice, fpartno) .. avez-vous un?

Comme les autres ont dit, le plan devrait expliquer se révéler utile pour expliquer le mystère.

Aucune de ces changements ont un effet sur la signification logique de la requête (par exemple, ils ne sont « pas ops »)

Le seul effet physique que COALESCE sur la clause ON serait d'empêcher l'optimiseur d'essayer d'utiliser un index pour ARI.FCINVOICE.

De même, le seul effet physique que le « > = CHAR (0) » pourrait avoir sur l'optimiseur peut être à elle prod à envisager d'utiliser une analyse de plage indexée (ou aussi Seek) sur un indice qui avait IRA. [fpartno] en elle.

Donc, ma conclusion serait que TOAD essaie de manipuler l'optimiseur en utilisant un index particulier sans réellement forcer à utiliser cet index avec un indice explicite. En fait, c'est un peu intelligent que le vrai problème avec les conseils d'optimisation T-SQL est leurs dépendances et la fragilité.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top