Frage

Ich bin mit Quest TOAD for SQL Server auf einem SQL Server 2000 Server.

Hier ist meine Abfrage:

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')

Hier ist nach Wahl des TOAD (mit Unterschieden markiert) ist:

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)***

Kann jemand mir bitte erklären, warum die coalesce und zusätzliche und Kontoauszugsgeschwindigkeit bis diese Abfrage um mehr als 50%?

War es hilfreich?

Lösung

Haben Sie einen Blick auf die tatsächlichen Ausführungspläne gemacht. Diese sollten Sie die verschiedenen Ansätze zeigen, dass SQL Server nahm in diese Abfragen ausgeführt werden.

Andere Tipps

Es ist definitiv ein sonderbares. Der Ausführungsplan sollten Ihnen sicher sagen, aber die Leistung ändert, wie dies in Datenbanken fast immer auf einen Index nach unten. So ist meine beste Vermutung ist, dass irgendwie SQL Server einen Index fehlte es verwenden könnte und das Hinzufügen dieser ungeraden Veränderungen machten es besser abheben.

Aber wenn Sie schauen ‚warum‘ beteiligt zu lernen, so dass Sie beim nächsten Mal Ihrer Abfrage schreiben können schneller in erster Linie zu sein, gibt es wirklich nichts gibt.

Eine vollständige WAG:

Ich werde das fpartno erraten, einen „nicht null“ Zustand auf sie hat (so die hinzugefügte Filter immer passiert), und dass Toad geschieht zu wissen, dass SQLServer nicht intelligent genug ist, dass die> = CHAR (0) zu erkennen ist immer wahr. So dies legt nahe, dass Toad in einer sehr schrägen Art und Weise versucht, zu führen, den Optimierer zu verwenden etwas, das fpartno in ihm hat. Das ist etwas, könnte ein Composite-Index auf (fcinvoice, fpartno) sein .. tun Sie einer von denen haben?

Wie die anderen gesagt, erklären den Plan als hilfreich erweisen sollte das Geheimnis zu erklären.

Keine dieser Änderungen haben keine Auswirkungen auf die logische Bedeutung der Abfrage (das heißt, sie sind „keine ops“)

Der einzige physikalische Effekt, dass der COALESCE auf der ON-Klausel aus dem Optimierungsprogramm zu verhindern wäre versucht, einen Index für ARI.FCINVOICE zu verwenden.

Auch der einzigen physikalische Effekt, dass der „> = CHAR (0)“ auf dem Optimierer haben könnte Macht zu prod es mit einem indizierten Bereich Scan zu prüfen (oder auch eine Suche) auf ein Index, der ARI hatte. [fpartno] drin.

So meine Schlussfolgerung wäre, dass TOAD versucht, den Optimierer in Verwendung einen bestimmten Index zu manipulieren, ohne tatsächlich zwingen es diesen Index mit einem expliziten TIPP zu verwenden. Eigentlich, das Art klug ist, als das eigentliche Problem mit den T-SQL-Optimierungshinweisen sind ihre Abhängigkeiten und Zerbrechlichkeit.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top