2016-07-26 8 views
0

SQL Server Management Studio 2008 R2Abgeleitete Tabelle where-Klausel Optimierung

Ich habe einen Blick (ziemlich langer SQL-Code, der eine Reihe von abgeleiteten Tabellen ist), die von verschiedenen Benutzern verwendet wird Abfrage und gespeicherte Prozeduren auf ~ 4.000.000 laufen Aufzeichnungen. Die folgende Abfrage wird in ungefähr 10 Minuten ausgeführt.

Select * from dbo.[vw_name] 

Ich versuche, diese gleiche Ansicht zu verwenden, um Informationen für 1 Datensatz zu ziehen, aber die Abfrage dauert noch ~ 10 min:

Select * from dbo.[vw_name] where ln=1234567890 

Es scheint, als ob die Ansicht alle 4.000.000 Datensätze verarbeitet und dann meine where-Klausel anwenden. Ich konnte die Ansicht in eine Tabellenwert-Funktion replizieren und die Abfragezeit auf ~ 10 Sekunden für einen einzelnen Datensatz erhöhen (ich nehme an, weil ich die Where-Klausel in die erste abgeleitete Tabelle statt in die sehr genaue einfügen konnte) Ende). Gibt es Überlegungen, wie Sie das Optimierungsprogramm dazu bringen, die where-Klausel zuerst zu berücksichtigen, wenn Sie die Ansicht abfragen?

Hinzufügen von Ansichts Abfrage:

SELECT  AsOfDate=GETDATE() 
     ,A1.* 
     ,Onsite_Flag= CASE 
         WHEN A1.[columnname]=1 AND A1.[columnname]=0 THEN 1 
         WHEN A1.[columnname]=5 AND A1.[columnname]=0 THEN 1 
         WHEN A1.[columnname] IN (12,31,33,34,35,38,52,54,59) THEN 1 
         ELSE 0 
         END 
     ,A1.Allowable_Flag 
     ,Achieved_Flag= CASE 
         WHEN A1.[columnname]=1 THEN 
          CASE 
          WHEN A1.[columnname] LIKE 'name%' 
          AND A1.[columnname]>=A1.[columnname] 
          AND (A1.[columnname] LIKE '%LOL%' OR A1.[columnname]='test') THEN 1 
          WHEN A1.[columnname]='qwerw' AND A1.[columnname]=4 THEN 1 
          WHEN A1.[columnname]='aerr33' AND A1.[columnname]=4 THEN 1 
          WHEN A1.[columnname]='asdf45' AND A1.[columnname] IS NOT NULL THEN 1 
          ELSE 0 
          END 
         ELSE 0 
         END 
     ,IM_Flag= CASE 
        WHEN A1.[columnname] IN(12,38) THEN 1 
        WHEN A1.[columnname]=1 AND A1.[columnname]=24 THEN 1 
        ELSE 0 
        END 
FROM  (SELECT  [columnname].... 
        ,[Name]=LTRIM(RTRIM(V1.A1FNAM)) + ' ' + LTRIM(RTRIM(V1.A1LNAM)) 
        ,LocationType= CASE WHEN LH1.[columnname]=2 THEN nLT.[columnname] ELSE LT.[columnname] END 
        ,LocationTypeID=CASE WHEN LH1.[columnname]=2 THEN nLT.[columnname] ELSE LT.[columnname] END 
        ,Location=CASE 
           WHEN DLD1.[columnname] IS NULL THEN DLD1.[columnname] 
           WHEN LH1.[columnname] IN (2,8) THEN DLD1.[columnname] + ' - ' + DLD2.[columnname] 
           ELSE DLD1.[columnname] 
           END 
        ,Allowable_Flag= CASE 
             WHEN CU1.[columnname]='1234' THEN 1 
             WHEN FCM.[columnname]='Y' THEN 0 
             WHEN MLD.[columnname]='24' THEN 0 
             WHEN INV.[columnname] LIKE '436573456%' THEN 1 
             WHEN INV.[columnname] LIKE '4526%' THEN 1 
             WHEN DSR.[columnname]='1020' THEN 1 
             ELSE 0 
             END 
        ,RN=ROW_NUMBER()OVER(PARTITION BY L.LoanNumber ORDER BY (CASE WHEN DM.Departments_ID=24 THEN 1 ELSE 0 END) DESC,LH1.LocationDate DESC) 
     FROM  server_name_3.dbo.[tablename] DSR 
     LEFT JOIN .... 
     OUTER APPLY SERVER_name_2.dbo.fnc_DT (LH1.[columnname], LH1.[columnname]) DLD1 
     OUTER APPLY SERVER_name_2.dbo.fnc_DT (DLD1.[columnname], DLD1.[columnname]) DLD2 
     LEFT JOIN (SELECT field1, field2,... 
        FROM server_name_3.dbo.SRVDSR DSR 
        LEFT JOIN ... 
        INNER JOIN (SELECT field1, MAX(field2) as field2 FROM SERVERNAME1.dbo.[tablename] WHERE field3=157 GROUP BY field1) CUO ON CUO.field1=R.field1 
        GROUP BY DSR.field1 
        ) CP_Req ON DSR.field1=CP_Req.field1 

     ) A1  
WHERE A1.RN=1 
+1

Siehe http://www.databasejournal.com/features/mssql/article.php/3867651/SQL-Server-Indexed-Views.htm –

+0

Ich bin nicht in der Lage, die Ansicht SCHEMABIND, wie es mehrere Datenbanken – Czar

Antwort

0

(1) Stellen Sie sicher, auf dem "ln" Feld ein Index gibt. (2) Veröffentlichen Sie die Abfrage der Ansicht und wir werden sehen, dass sie optimiert werden kann - verschleiern Sie Felder, wenn Sie dies aus Sicherheitsgründen benötigen.

+0

Ansicht sql hinzugefügt trifft über – Czar

0

Wenn die Zeile, nach der Sie suchen, von dieser ROW_NUMBER-Funktion stammt, dann muss yes die gesamten Ergebnisse erzeugen, bevor Ihnen dieser Datensatz gesendet werden kann. Sie könnten versuchen, die Abfrage mehr deterministisch von selbst GETDATE und ROW_NUMBER aus der Sicht zu entfernen und stattdessen die Felder in der Abfrage der Ansicht sind:

; WITH DateNow 
AS ( 
    SELECT DateNow = GETDATE() 
    ) 
SELECT d1.DateNow 
    , v1.* 
    , ROW_NUMBER() OVER... 
FROM YourView v1 
    , DateNow d1 

, die noch die gesamten Ergebnisse zu produzieren, aber die Ansicht selbst könnte schneller sein. Ich kann Ihnen einen allgemeinen Rat geben, wenn es hilft. Eine doppelte Wildcard-Suche, "% foo%", ist ein Performance-Killer, aber ich weiß, dass du oft dabei bist. Sie könnten prüfen, ob Sie diese abgeleiteten Tabellen in indizierte Sichten umwandeln oder Ihre zahlreichen Zeichenkettenvergleiche in persistente berechnete Spalten einfügen. Ich denke, die beste Lösung, wenn die Daten etwas veraltet sein können, besteht darin, diese Abfrage einmal nachts auszuführen und die Ergebnisse in eine einzige Tabelle, einen Datamart, einzufügen, der sehr schnell abgefragt werden kann.