2015-01-20 71 views
1

我有一個查詢像這樣:提高性能上內部聯接

SELECT 
    Mnum, Label , Lvalue ,[Property Type] , RowID, ColumnID, DisplayOrder 
FROM 
    (SELECT 
     a.Mnum as Mnum, -- 420 fields go here 
    FROM -- 51 joins go here 
    ) AS MainQuery 
UNPIVOT (LabelValue FOR LabelName IN (--420 fields go here)) 
AS UnpvtQuery 

INNER JOIN 
    ReportFieldsLookup rfl on rfl.label = LabelName and rfl.PropType = [PropertyType] 

上面所示的查詢的向下斷裂如下:

將執行內上述查詢的一部分加入多個表格(恰好51個內部聯接),併爲每個ID吐出420列。我在這個結果表上執行Unpivot操作。這將導致每個ID有420行。

SELECT 
    Mnum, Label , Lvalue ,[Property Type] , RowID, ColumnID, DisplayOrder 
FROM 
    (SELECT 
     a.Mnum as Mnum, -- 420 columns go here 
    FROM -- 51 joins go here 
    ) AS MainQuery 
UNPIVOT ( LabelValue FOR LabelName IN (--420 fields go here)) 

結果表將包含以下的列:

Mnum   varchar 
    LabelName  varchar 
    Lvalue  varchar 
    PropertyType varchar 

樣本數據:

8045 Assoc Amenities   N/A   C/C 
8045 Assoc Fees Include  n/a   C/C 
8045 Assoc Pet Rules   N/A   C/C 
8045 Attached/Detached  Detached C/C 
8045 Avail for Lease   No   C/C 
8045 BRELA     No   C/C 
6012 Assoc Amenities   N/A   C/C 
6012 Assoc Fees Include  n/a   C/C 
6012 Assoc Pet Rules   N/A   C/C 
6012 Attached/Detached  Detached C/C 
6012 Avail for Lease   No   C/C 
6012 BRELA     No   C/C 
7129 Assoc Amenities   AV   SFR 
7129 Assoc Fees Include  yes   SFR 
7129 Assoc Pet Rules   N/A   SFR 
7129 Change Date    N/A   SFR 
3278 Assoc Amenities   Yes   lnd 
3278 Assoc Fees Include  0   lnd 
3278 Assoc Pet Rules   N/A   lnd 
3278 Directions    abc   lnd  
3278 Disclosure    aff   lnd 

當我與24 Mnum's運行查詢的上面顯示部分作爲輸入它需要我約6秒鐘來執行查詢。

現在我有一個包含以下幾列另一個表(ReportFieldsLookup):

rownum bigint, 
Aid  varchar 
reportid bigint 
Label varchar 
PropType varchar 
DisplayOrder bigint 

的樣本數據:

1 101 1 Assoc Amenities   C/C  1 
2 101 1 Assoc Fees Include  C/C  2 
3 101 1 Assoc Pet Rules   C/C  3 
4 101 1 Avail for Lease   C/C  4 
5 101 1 Attached/Detached  C/C  5 
6 101 1 BRELA     C/C  6 
7 101 1 Assoc Amenities   SFR  1 
8 101 1 Assoc Fees Include  SFR  2 
9 101 1 Assoc Pet Rules   SFR  3 
10 101 1 Change Date    SFR  4 
11 101 1 Assoc Amenities   lnd  1 
12 101 1 Assoc Fees Include  lnd  2 
13 101 1 Assoc Pet Rules   lnd  3 
14 101 1 Directions    lnd  4 
15 101 1 Disclosure    lnd  5 

,我試圖加入上述的兩種表。

INNER JOIN 
    ReportFieldsLookup rfl ON rfl.label = LabelName AND rfl.PropType = [PropertyType] 

結果表:

8045 Assoc Amenities   N/A   C/C  1 
8045 Assoc Fees Include  n/a   C/C  2 
8045 Assoc Pet Rules   N/A   C/C  3 
8045 Attached/Detached  Detached C/C  4 
8045 Avail for Lease   No   C/C  5 
8045 BRELA     No   C/C  6 
6012 Assoc Amenities   N/A   C/C  1 
6012 Assoc Fees Include  n/a   C/C  2 
6012 Assoc Pet Rules   N/A   C/C  3 
6012 Attached/Detached  Detached C/C  4 
6012 Avail for Lease   No   C/C  5 
6012 BRELA     No   C/C  6 
7129 Assoc Amenities   AV   SFR  1 
7129 Assoc Fees Include  yes   SFR  2 
7129 Assoc Pet Rules   N/A   SFR  3 
7129 Change Date    N/A   SFR  4 
3278 Assoc Amenities   Yes   lnd  1 
3278 Assoc Fees Include  0   lnd  2 
3278 Assoc Pet Rules   N/A   lnd  3 
3278 Directions    abc   lnd  4 
3278 Disclosure    aff   lnd  5 

它需要大約30多秒。

我該怎麼做才能減少執行時間?

回答

1

您可以做的第一件事是確保您在所引用的列上的所有表中都有索引來創建聯接。

假設這是已經完成,你需要更多的性能,這是一個很大的內部連接,所以我會做一個索引視圖上的代碼的MainQuery部分:

-- Create a view from the query 
CREATE VIEW dbo.MnumIndexedView 
WITH SCHEMABINDING 
AS 
SELECT a.Mnum as Mnum, -- 420 fields go here 
    FROM -- 51 joins go here 
GO 

-- Index the view 
CREATE UNIQUE CLUSTERED INDEX idx_cl_mnumindexedview 
ON dbo.MnumIndexedView(Mnum); 
GO 

-- Your new query, this time using the indexed view. 
SELECT Mnum, Label, Lvalue, [Property Type], RowID, ColumnID, DisplayOrder 
FROM  dbo.MnumIndexedView WITH (NOEXPAND) 
UNPIVOT (LabelValue FOR LabelName IN (--420 fields go here)) 
AS 
INNER JOIN ReportFieldsLookup rfl 
     ON rfl.label = LabelName AND rfl.PropType = [PropertyType] 

你不能把整個東西在索引視圖中,因爲我認爲PIVOTUNPIVOT不支持索引視圖。但是,堅持來自多個內部聯接的數據應該有希望爲您帶來更好的性能。

請注意,這需要some additional options to be enabled,因爲SQL Server在實現索引視圖創建時可能會有點挑剔。

另請注意,在索引視圖的查詢中使用了WITH (NOEXPAND)。在非企業版本的SQL Server中,這是必要的,否則優化器只會查詢基礎表並且不會看到任何好處。

+0

哇......慢下來!爲什麼直接索引視圖而不確定基本索引是否存在? – 2015-01-21 01:13:50

+0

好的,我在開始時添加了一部分,以確保他在連接中引用的所有列上都有索引。但是,如果他這麼做太瘋狂了,那麼最終可能會造成寫入性能下降/數據庫管理系統開銷,以便建立所有這些索引(更不用說大量的工作了),因爲它只是具有首先完成索引視圖。 – 2015-01-21 03:58:20