2016-07-26 64 views
0

SQL Server Management Studio中2008 R2派生表where子句優化

我有一個觀點(相當漫長的SQL代碼是一系列派生表)所使用的運行查詢幾個不同的用戶和〜4000000存儲過程記錄。以下查詢在大約10分鐘內執行。

Select * from dbo.[vw_name] 

我試圖使用同樣的觀點拉動信息1分的記錄,但查詢仍然需要〜10分鐘:

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

它好像在視圖處理所有400萬次的記錄和然後應用我的where子句。我能夠將視圖複製到一個表值函數中,並將單個記錄的查詢時間增加到〜10秒(我假設我能夠在第一個派生表中插入where子句而不是在結束)。有關如何強制優化器在查詢視圖時首先考慮where子句的想法?

添加視圖查詢:

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

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

+0

我無法SCHEMABIND視圖,因爲它擊中多個數據庫 – Czar

回答

0

(1)確保有一個在 「LN」 字段上的索引。 (2)發佈視圖的查詢,我們會看到它可以進行優化 - 如果您需要出於安全目的對域進行模糊處理。

+0

視圖sql added以上 – Czar

0

如果您要搜索的行號來自該ROW_NUMBER函數,那麼是的,它必須在能夠向您發送一條記錄之前生成整個結果。你可能會嘗試使查詢更確定從視圖中刪除了GETDATE和ROW_NUMBER本身,而是包含在該視圖的查詢這些領域:

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

這仍然要產生整個結果,但視圖本身可能會更快。如果有幫助,我可以給你一些一般建議。雙通配符搜索'%foo%'是一個性能殺手,但我知道你經常被它困住。您可以考慮將這些派生錶轉換爲索引視圖,或將多個字符串比較添加到持久計算列中。如果數據可能有些陳舊,我認爲最好的解決方案是在夜間運行此查詢一次,並將結果插入單個表中,這是一個數據集市,它將以超快的速度進行查詢。