我有一個存儲過程,它通過UNION ALL
組合來自多個表的數據。如果傳遞到存儲過程的參數不適用於特定的表,我試圖通過使用「幫助位」來「短路」該表。 @DataSomeTableExists
並在WHERE
子句中添加相應的條件,例如,Awkward JOIN導致性能不佳
存儲過程中的一個(psuedo)表有點尷尬,給我帶來一些悲傷。
DECLARE @DataSomeTableExists BIT = (SELECT CASE WHEN EXISTS(SELECT * FROM #T WHERE StorageTable = 'DATA_SomeTable') THEN 1 ELSE 0 END);
...
UNION ALL
SELECT *
FROM REF_MinuteDimension AS dim WITH (NOLOCK)
CROSS JOIN (SELECT * FROM #T WHERE StorageTable = 'DATA_SomeTable') AS T
CROSS APPLY dbo.fGetLastValueFromSomeTable(T.ParentId, dim.TimeStamp) dpp
WHERE @DataSomeTableExists = 1 AND dim.TimeStamp >= @StartDateTime AND dim.TimeStamp <= @EndDateTime
UNION ALL
...
注:REF_MinuteDimension
無非是用分鐘爲增量smalldatetimes更多。
(1)執行計劃(下圖)表示對嵌套循環運算符的警告,表示不存在連接謂詞。這可能不是很好,但表格之間確實沒有自然連接。有沒有更好的方法來編寫這樣的查詢?對於T中的每個ParentId,我希望@StartDateTime和@EndDateTime之間的每分鐘UDF的值。
(2)即使當@DataSomeTableExists = 0
時,在該查詢中的表上存在由SET STATISTICS IO ON
報告的表的I/O活動和實際執行計劃。執行計劃報告14.2%的成本,考慮到這些表格甚至不適用於這種情況。
SELECT * FROM #T WHERE StorageTable = 'DATA_SomeTable'
重新排空。
這是我寫查詢的方式嗎?爲什麼幫助器位或空的T短路這個查詢?
你應該改變'DECLARE'的事情是:'聲明@DataSomeTableExists位= 0 如果存在(SELECT * FROM #T WHERE StorageTable = 'DATA_SomeTable') begin \t set @DataSomeTableExists = 1 end'。這很難讀,所以這裏是[pastebin](http://pastebin.com/4y0VTJCD)。那麼爲什麼'CROSS JOIN'查詢中還沒有「短路」'WHERE'參數呢?我應該提到,如果這樣做能夠奏效,我就不知道了,因爲寫一個sproc是一種奇怪的方式。 –