簡體   English   中英

派生表where子句優化

[英]Derived table where clause optimization

SQL Server Management Studio 2008 R2

我有一個視圖(相當長的sql代碼,它是一系列派生表),供大約4,000,000條記錄上運行查詢和存儲過程的幾個不同用戶使用。 以下查詢將在大約10分鍾后執行。

Select * from dbo.[vw_name]

我正在嘗試使用相同的視圖提取1條記錄的信息,但是查詢仍然需要10分鍾左右:

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

好像該視圖正在處理所有4,000,000條記錄,然后應用我的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)確保“ ln”字段上有一個索引。 (2)發布視圖的查詢,我們將看到它可以進行優化-如果出於安全目的需要對字段進行混淆。

如果您要搜索的行號來自該ROW_NUMBER函數,則可以,它必須生成整個結果,然后才能向您發送該條記錄。 您可以嘗試通過從視圖本身中刪除GETDATE和ROW_NUMBER來使查詢更具確定性,而將這些字段包括在視圖查詢中:

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

那仍然必須產生全部結果,但是視圖本身可能會更快。 如果有幫助,我可以給您一些一般性建議。 雙通配符搜索'%foo%'是性能殺手,但我知道您經常被它困住。 您可以考慮將那些派生表轉換為索引視圖,或者將許多字符串比較添加到持久化的計算列中。 我認為,如果數據可能有點過時,最好的解決方案是晚上運行一次此查詢,然后將結果插入到單個表(即數據集市)中,這將非常快速地進行查詢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM