2011-10-18 57 views
0

我意識到這個例子完全是人爲的,但我在這裏尋找一個一般的經驗法則;這兩個查詢之間的性能觀點有什麼不同嗎?速度更快,引用外部表中的屬性還是比較參數?

實施例1:參考表外:

select o.id, o.name, 
(select count(*) from inner_table i1 where i1.outerid = o.id), 
(select sum(i2.amount) from other_inner_table i2 where i2.outerid = o.id) 
from outer_table o 
where o.id = @outerid 

實施例2:直接針對參數進行比較:

select o.id, o.name, 
(select count(*) from inner_table i1 where i1.outerid = @outerid), 
(select sum(i2.amount) from other_inner_table i2 where i2.outerid = @outerid) 
from outer_table o 
where o.id = @outerid 

我主要使用SQL Server 2008 R2,但我很對任何RDMS特有的答案感興趣。

更新:

我意識到這是hightly語境;我想我只是好奇,如果這只是一個風格的選擇,或者如果有情況下,這實際上會有所作爲。我意識到我可以對特定情況進行「測試並查看」 - 但這不是我追求的答案。

+3

測試一下,看看。 –

+2

在一個使用空表(在2008下,不是R2)的快速實驗中,在這兩種情況下,謂詞'outerid = @ outerid'用於內部表(即優化程序將示例1轉換爲類似於示例2的東西)。但正如其他人所說,你需要在你的系統上試用它,包括你的數據,索引等。 –

+0

@Damien_The_Unbeliever - 如果你將你的評論作爲答案(帶有一些背景數據等),我會接受它作爲答案,因爲它是最接近我在這裏尋找的。 – DanP

回答

1

我創造了一些完全空表,只有所需的列,使您的查詢運行:

CREATE TABLE [dbo].[inner_table](
    [outerid] [int] NOT NULL 
) 
CREATE TABLE [dbo].[other_inner_table](
    [outerid] [int] NOT NULL, 
    [amount] [int] NOT NULL 
) 
CREATE TABLE [dbo].[outer_table](
    [id] [int] NOT NULL, 
    [name] [varchar](30) NOT NULL 
) 

我然後轉身上執行計劃和執行這兩個查詢。在這兩種情況下,這表明所有3個表正在被掃描(如預期的那樣,沒有/低行)。特別地,針對inner_table掃描具有謂詞:

[DBName].[dbo].[inner_table].[outerid] as [i1].[outerid]=[@outerid] 

和針對other_inner_table掃描具有謂詞:

[DBName].[dbo].[other_inner_table].[outerid] as [i2].[outerid]=[@outerid] 

也就是說,在第一示例中,優化器已經識別出該外部子句條件where o.id = @outerid意味着在子查詢中,o.id總是等於@outerid,並且已經執行了該替換。

一般來說,除非出現性能問題,否則不應該通過手動轉換查詢來「幫助」SQL。有300種不同的優化方式可供優化器使用 - 您可能不會選擇最優的方案。

1

SQL的優缺點之一是它的高級別,所以只有通過獲取解釋計劃和測試特定案例以確保結果才能確定。回答大多數數據庫問題並不罕見,這取決於...。

0

有沒有簡單的方法來回答這個問題;你的索引是什麼樣的?限制?統計? i2.outerid上的數據分佈是什麼?你的服務器有多少內存?

有時性能調整是一門科學;通常它是巫術。 :)