提高SQL Server临时表选择的性能

问题描述 投票:0回答:1

我有一个临时表,其结构如下。它返回了380万条记录。它需要5分钟。有没有办法提高性能。这个临时表的正确索引应该是什么?我们需要使用分区吗?如果是这样,如何正确使用它

CREATE TABLE  #FinalResultTable                
 (              
    RowNum INT  PRIMARY KEY NONCLUSTERED IDENTITY(1,1),              
    [Disclosure Category] NVARCHAR(250) NULL,              
    [Line #] INT NULL,                 
    [AllocationProcessId] BIGINT NULL,              
    [Allocation Name] VARCHAR(50) NULL,                
    [Line Description (Long)] NVARCHAR(3000) NULL,               
    [Line Description (Short)]  NVARCHAR(500) NULL,         
    [UniqueTransactionId] INT NULL,         
    [TransactionName] VARCHAR(125) NULL,                
    [Partner #] INT NULL,                
    [Partner Name] VARCHAR(2000) NULL,                
    [RuleName] VARCHAR(128) NULL,                
    [Tag Group1] NVARCHAR(75) NULL,                
    [Tag Group2] NVARCHAR(75) NULL,                
    [Tag Group3] NVARCHAR(75) NULL,                
    [Tag Group4] NVARCHAR(75) NULL,                
    [Segment Start Date] DATE NULL,                
    [Segment End Date] DATE NULL,                
)   


CREATE CLUSTERED INDEX IX_FinalResultTable 
    ON #FinalResultTable ([Partner #],[Disclosure Category]);

在下面的选择数据之前从许多其他表插入此临时表。

SELECT 
 [RowNum],              
[Disclosure Category],              
[Line #],                 
[AllocationProcessId],              
[Allocation Name],                
[Line Description (Long)],               
[Line Description (Short)],         
[UniqueTransactionId],         
[TransactionName],                
[Partner #],                
[Partner Name],                
[RuleName],                
[Tag Group1],                
[Tag Group2],                
[Tag Group3],                
[Tag Group4],                
[Segment Start Date],                
[Segment End Date]                
FROM #FinalResultTable
sql sql-server sqlperformance
1个回答
1
投票

如果您计划检索所有记录,则无法使用索引加速SELECT。索引适用于选择具有确定标准的特定行,或以特定顺序获取行(您的SELECT也没有任何ORDER BY)。

值得一提的是你如何装载你的桌子。使用CREATE TABLE + INSERT INTO会使SQL Server记录每一行插入,并且比执行SELECT INTO(不首先创建表)需要花费更长的时间,因为它具有最少的日志记录。如果切换到此方法,请确保从SELECT正确转换数据类型。

所以代替:

IF OBJECT_ID('tempdb..#FinalResultTable') IS NOT NULL
    DROP TABLE #FinalResultTable

CREATE TABLE  #FinalResultTable                
(              
    /*Columns*/              
)

INSERT INTO #FinalResultTable
(
    /*Columns*/  
)
SELECT
    /*Columns*/
FROM
    /*Tables*/

你切换到:

IF OBJECT_ID('tempdb..#FinalResultTable') IS NOT NULL
    DROP TABLE #FinalResultTable

SELECT
    /*
    Columns with the proper data type cast (if needed), for example:

        Column1 = CONVERT(VARCHAR(100), Column1 + 'SomeText'),
        Column2 = CONVERT(INT, VarcharColumn)
    */
INTO
    #FinalResultTable
FROM
    /*Tables*/

如果您不对数据进行排序,并且刚刚使用此临时表来选择所有行,则可以避免在其上创建任何索引,因为生成一个或重新排序所有数据(如果它是群集的)需要一段时间。所以不要创建你的聚集索引IX_FinalResultTable,也不要为你的PRIMARY KEY列声明你的IDENTITY,使用RowNum INT IDENTITY。这将使您的临时表成为堆而不是实际表,请注意,如果您曾经使用[Partner #]进行搜索,那么大多数过滤后的选择将大大降低性能。

如果确实需要[Partner #], [Disclosure Category]的聚簇索引,那么加载这些2已经排序的表实际上会减少索引创建时间。确保在加载表之后创建索引,而不是之前,因为它更快。

SELECT
    /*
    Columns with the proper data type cast (if needed), for example:

        Column1 = CONVERT(VARCHAR(100), Column1 + 'SomeText'),
        Column2 = CONVERT(INT, VarcharColumn)
    */
INTO
    #FinalResultTable
FROM
    /*Tables*/
ORDER BY
    [Partner #],            -- Or the expression that resolves as this column
    [Disclosure Category]   -- Or the expression that resolves as this column

另外值得一提的是,SELECT的列越少,SELECT就越快。传输速度还取决于客户端和服务器之间的网络连接以及它使用的连接类型。

© www.soinside.com 2019 - 2024. All rights reserved.