提高内连接的性能

时间:2015-01-20 23:03:52

标签: sql sql-server sql-server-2012 inner-join

我有一个像这样的查询:

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 个答案:

答案 0 :(得分:1)

您可以做的第一件事是确保在被引用的列的所有表中都有索引来进行连接。

假设已经完成并且你需要更多的性能,那就是很多内部联接,所以我在你的代码的MainQuery部分做了一个索引视图: / p>

-- 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中,这是必要的,否则优化器将只查询基础表,并且您不会看到任何好处。