Cte

需要一種更快的方法將行連接到列中——目前使用 CTE

  • April 16, 2014

目前,我們正在使用我創建的從多個表中提取數據的視圖。關於這一點的主要因素是獲得規範的視圖涉及 CTE 和字元串連接的混合,以將多行組合成一列(多次)。雖然該視圖有效,但使用者最近抱怨它太慢了。

目前,視圖設置如下所示:

;
With thing1 AS
(
SELECT DISTINCT
           /* huge block of code with joins and such  
           that gets the individual fields and concatenates  
           personnel names to one row */
)
,
thing2 AS
(
   SELECT  TaskName,
           Company,
           Lease,
           TaskBegin,
           TaskEnd,
           Field,
           Personnel,
           Invoice,
           InvDate,
           InvTot,
           ROW_NUMBER() OVER (Partition by TaskName ORDER BY [TaskName] ASC) rn
   FROM thing1 
)

SELECT  TaskName,
       Company,
       Lease,
       Field,
       ISNULL(Personnel, '') as 'Personnel',
       TaskBegin,
       TaskEnd,
       ISNULL (STUFF( (SELECT ', ' + Invoice 
               FROM thing1
               WHERE (thing1.TaskName = thing2.TaskName)
               AND thing2.rn = 1
               ORDER BY Invoice
               FOR XML PATH('')), 1, 1, ''), '') AS 'Invoice',
       ISNULL (STUFF( (SELECT ', ' + InvDate 
               FROM thing1
               WHERE (thing1.TaskName = thing2.TaskName)
               AND thing2.rn = 1
               ORDER BY Invoice
               FOR XML PATH('')), 1, 1, ''), '') AS 'InvoiceDate',
       ISNULL (STUFF( (SELECT ', ' + InvTot 
               FROM thing1
               WHERE (thing1.TaskName = thing2.TaskName)
               AND thing2.rn = 1
               ORDER BY Invoice
               FOR XML PATH('')), 1, 1, ''), '') AS 'InvoiceTotal'
   FROM thing2 WHERE rn = 1

GO

所以它按預期工作。問題是,一旦我到達連接 Invoice、InvDate 和 InvTot 的最終 SELECT,查詢就會從不需要一秒鐘(即來自 thing2 的直接 SELECT)變為需要 7 秒鐘來執行它的過程。(平均時間約為 5 秒。)我相當確信部分責任在於不斷增長的數據庫——該視圖在測試環境中載入速度要快得多,其中的記錄要少得多。

因此,我的問題是: 是否有可能在數據庫上以一種更快、更少資源密集型的方式來解決這個問題?

看起來您的程式碼中的問題是對 CTE 的多次訪問以及您在其中擁有的所有復雜邏輯。您應該嘗試使用 UNPIVOT/PIVOT 一次性完成所有操作。我在這裡做了類似的事情:http: //spaghettidba.com/2011/10/13/concatenating-multiple-columns-across-rows/

在我的例子中,你會發現不同語言的句子連接(不完全是你的意思)之後),但在我看來,您可以使用相同的技術。

聽起來您所擁有的是一個 EAV 模式(因此程式碼塊主要連接到相同的片段),您需要轉置以進行報告。如果是這種情況,那麼您可能會發現該PIVOT功能可以使這些 CTE 更高效(在程式碼可讀性和執行執行時間方面):http://technet.microsoft.com/en-us/library/ms177410(v=sql. 105).aspx

引用自:https://dba.stackexchange.com/questions/60886