提高SQLServer临时表选择的性能

提高SQLServer临时表选择的性能,sql,sql-server,sqlperformance,Sql,Sql Server,Sqlperformance,我有一个临时表,其结构如下所示。它返回了380万条记录。需要5分钟。有没有办法提高性能。此临时表的正确索引应该是什么?我们需要使用分区吗?如果是,如何正确使用它 CREATE TABLE #FinalResultTable ( RowNum INT PRIMARY KEY NONCLUSTERED IDENTITY(1,1), [Disclosure Category] NVARCHAR

我有一个临时表,其结构如下所示。它返回了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
如果计划检索所有记录,则无法使用索引加速SELECT。索引适用于选择具有确定条件的特定行,或按您选择的没有任何顺序的特定顺序获取行

值得一提的是如何加载表格。使用CREATETABLE+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,也不要为标识列声明主键,请使用RowNum INT IDENTITY。这将使您的临时表成为堆而不是实际表,请注意,如果您使用[Partner]搜索,则大多数筛选的select将大大降低性能

如果您确实需要[Partner]、[Exposition 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

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

您可以通过不创建表而改为选择到来加快表的加载速度。查询的性能在很大程度上取决于联接和筛选器。您真的需要临时表上的聚集索引吗?其中一个问题是如何填充临时表,这是我们无法看到的。另一个问题是返回380万行,这太多信息无法显示。此选择似乎读取了每一行。你不能用索引来改善这一点。当您可以将读取每一行的扫描更改为读取最少行数的查找时,大多数改进都会出现。如果您知道正在对临时表执行哪些查询,那么创建聚集索引和其他索引(如有必要)将非常有效。一个拥有380万的报告如何被认为是可行的?这对于任何人来说都是太多的数据,无法作为报告使用。