2010-06-24 49 views
0

我正在用Sql Server 2008創建一個存儲過程,它將返回2個結果集。第一個查詢返回一個結果集,我想在第二個查詢中重新使用這個結果集作爲子查詢(請參見下面的示例)。但是,由於第一個查詢和子查詢本質上返回相同的數據,所以我想知道是否有一些緩存meachanism可以使用。有可能這樣做嗎?我正在嘗試優化性能。用Sql Server 2008進行子查詢緩存

SELECT * 
FROM Employees 
WHERE BossId = 1 

SELECT * 
FROM CostCenters 
WHERE EmployeeId IN (
    SELECT EmployeeId 
    FROM Employees 
    WHERE BossId = 1 
) 

P.S.這個例子是一個簡化的問題。

+0

您正在進行子查詢的查詢的代價如何? – 2010-06-24 17:11:07

回答

1

據我所知,你需要使用臨時表或表變量。 A comparison of the two在這裏。

以下使用OUTPUT子句填充表變量並在一個語句中進行選擇。

declare @MatchingResults table 
(
EmployeeId int primary key --Other Columns 
) 

INSERT INTO @MatchingResults 
OUTPUT INSERTED.* 
SELECT EmployeeId --Other Columns 
FROM Employees 
WHERE BossId = 1 


SELECT * 
FROM CostCenters 
WHERE EmployeeId IN (
    SELECT EmployeeId 
    @MatchingResults)) 
+0

如何使用表變量?我會獲得任何表演嗎? – Martin 2010-06-24 16:17:02

+0

請參閱編輯。是的,你可能會獲得性能,但看看執行計劃。有時臨時表可以在統計有所作爲的情況下表現更好。 – 2010-06-24 16:29:57

0

我能想到的最好的辦法是去與CTE

http://msdn.microsoft.com/en-us/library/ms190766.aspx

+0

儘管(大部分時間)這並未實現。我想,直到Quassnoi糾正我http:// stackoverflow。COM /問題/ 2855940 /使用-的與 - 子句中-SQL服務器/ 2856674#2856674 – 2010-06-24 16:34:07

1

表變量是您最佳的選擇。您也可以通過使用exists運營商子查詢,而不是in提高性能:

-- obviously the columns should match your Employees table 
declare @results table (
    employeeId int, 
    column1 varchar, 
    column2 int 
) 

insert into @results 
select * from Employees 
where BossId = 1 

-- using exists/not exists performs much better than in 
select * from CostCenters 
where exists (select 0 
       from @results as r 
       where CostCenters.employeeId = r.employeeId) 
1

緩存第一個查詢的數據可能不會導致更好的性能。當SQL Server收到查詢時,它將其分解爲簡單的步驟,選擇適當的索引和運算符並使用這些索引檢索數據。通過將第一個查詢的數據存儲在表變量或臨時表中,可以防止SQL Server在Employees表上使用任何索引。

如果您在使用JOIN它更容易看個究竟

SELECT c.* 
FROM CostCenters c INNER JOIN Employees e on c.EmployeeId=e.EmployeeId 
WHERE e.BossId=1 

當SQL Server看到這個查詢會檢查表的統計數據重寫查詢以同等學歷。如果BossId是一個高度選擇性的索引列,它可能會首先嚐試按此過濾。否則,它將使用EmployeeId列上的任何索引將兩個表中的行限制爲最小值,然後使用BossId查找正確的行並返回它們。

索引上的過濾操作非常快,因爲索引僅包含行數據的子集,更容易在內存中緩存,並且具有允許快速搜索的物理結構。

在遇到實際的性能問題之前,確實不應該嘗試對SQL Server的查詢優化器進行二次猜測。大多數情況下,您會阻止它選擇最佳執行計劃並導致性能下降