2012-07-23 30 views
0

我在某個日期時間段(即2012年5月1日至2012年5月31日)運行數據庫上覆雜查詢的列表。然後,我需要在2012年6月1日至2012年6月30日期間運行相同的查詢。然後加入報告目的的結果。重用一個表變量?

在查詢中,我用了幾個表變量來存放臨時數據。由於數據庫很大,表變量的大小也很大。有沒有一種方法可以重用這些表變量?

DROP,截斷不起作用。我是否必須從@table中刪除所有數據?如果是這樣,它會變慢嗎?因爲它有大量的數據,我必須對@table進行批量刪除嗎?

順便說一句,我必須把所有查詢放在一個SP文件中,因爲系統的設計方式,不能調用函數或其他SP。

感謝

=============================

沒有在查詢沒有循環。它的工作原理是:

選擇.....選擇.....更新.....加入......

做一組查詢日期2012/05/01至收取罰金。那麼需要2012年6月1日至2012年6月30日的同一組查詢。

在查詢中,裏面有很多邏輯,所以我們不能將這2個組合成一組查詢。由於系統設計,我們不能爲查詢調用函數或SP。必須先完成第一組查詢,然後按順序完成第二組查詢。

問題是數據太多,@table太大。如果我們可以重用@table,它將解決問題。

感謝

===============================

是,眼下,相同的代碼,爲2個不同的日期時間間隔重複兩次。但是,在代碼中,它具有一些合乎邏輯的內部,基於日期時間差異的不同過程。對不起,我無法發佈實際的代碼。但是,這個過程就像一個以不同日期時間段作爲參數的SP。

但是,在這種情況下我不能使用SP /函數,所以必須對相同的代碼進行兩次硬編碼。理想情況下,每次我重複代碼(現在需要重複3次)時,需要使用不同的@table(但現在需要重複3次),但由於數據大小的原因,如果我重複3次(@需要多次@table做邏輯部分)。

也許我最好用臨時表?所以我可以在開始新的'重複'時放棄它?

謝謝

+1

也許你可以顯示你的代碼。重用表變量意味着可能不需要的循環。即使對於一個循環來說,一個表變量可能不是必需的。看起來這個洋蔥可能有很多層。您爲我們做的越多,您的最終解決方案就越好。 – 2012-07-23 21:29:13

+0

我不明白你在那裏發佈的邏輯。 'select ... select ... update ... join' - 這是什麼意思?你怎麼從五月到六月?您的代碼如何知道運行這兩個月的報告?你有兩個與這些日期硬編碼幾乎相同的查詢? – 2012-07-23 21:41:29

+1

我認爲你正試圖在這裏微觀優化。不幸的是,因爲你的查詢設計選擇,這將會像刮犛牛腿,讓他遊得更快。 – 2012-07-23 22:00:12

回答

10

表變量未記錄在當前數據庫中,並且不受事務處理。爲什麼你認爲截斷或者刪除會比刪除更快?你試過這個嗎?

DECLARE @f TABLE(id INT); 

INSERT @f SELECT 1; 

BEGIN TRANSACTION; 
DELETE @f WHERE id = 1; 
ROLLBACK TRANSACTION; 

SELECT id FROM @f; 

沒有結果。現在,如果刪除已完全記錄在當前數據庫中(對於普通用戶表而言,這會使DELETE慢於TRUNCATE),那麼預計DELETE已被回滾,並且SELECT應該已返回數據。但是,不,刪除不是交易的一部分。那麼你可以邏輯推斷,那麼DELETETRUNCATE如果不完全相同,後者是允許的。

如果您必須使用表變量,只需使用刪除。如果你發現它很慢,可能不是因爲刪除,這可能是因爲你正在循環中重新使用表變量,而不是使用基於集合的操作。但是,當然,如果使用兩個不同的@table變量,而不是使用單個表變量並在兩者之間發出刪除,那麼您比我們中的任何人都處於更好的位置來測試代碼的速度。但我仍然認爲你的整個過程需要重新調查,因爲它在很多層面上對我而言聽起來不是最理想的。

1

當然,但你真正想要的不是一個表參數,而是你想要一個臨時表。

CREATE TABLE #my_temp_table (column1 int, column2 varchar(max), ...) 
INSERT INTO #my_temp_table (column1, column2) VALUES (...) 
-- Use the temporary table here 
DELETE FROM #my_temp_table 
INSERT INTO #my_temp_table (column1, column2) VALUES (...) 
-- Use the temporary table again 
DROP TABLE #my_temp_table 

編輯:提交者可能會說「因爲它傳遞到我的存儲過程旗READONLY我不能使用表變量」。在這種情況下,他可能會將其轉換爲臨時表格。

作爲一個側面說明,儘管SQL Server的文檔聲稱不是這種情況,但我已經看到臨時表執行比表變量更好的實例。我相信這是因爲我把TEMPDB放在了一個單獨的磁盤上,這個磁盤有很多可用的IO容量。

但請記住臨時表存在命名問題 - 如果它試圖爲臨時表創建命名衝突,則可以鎖定存儲過程。表變量不會遇到這個問題。

+0

是的,也許這是做到這一點的方法。只是好奇,它應該有辦法'重置'表變量,因爲它是一個變量,不是嗎?謝謝。 – urlreader 2012-07-23 21:51:57

+0

這與從表變量中刪除有什麼不同?你認爲#temp表總是比表變量好嗎? – 2012-07-23 21:53:04

+0

我認爲當#table中有很多數據時,drop和然後創建#table比直接刪除數據要快得多。 – urlreader 2012-07-23 21:57:51