除索引外的SQL Server调整建议

时间:2018-11-28 15:41:54

标签: sql sql-server performance sql-tuning

我正在处理一个SQL查询,该查询需要许多自连接表来创建聚合函数,如下所示。

SELECT  
    tab1.foo, 
    tab1.bar, 
    tab1.baz, 
    tab1.bam/tab2.bam as bam_ratio, 
    RANK() OVER (PARTITION BY tab1.bar, tab1.baz ORDER BY tab1.foo DESC) RANK
FROM 
    (SELECT 
         foo, 
         bar, 
         baz, 
         bam
     FROM 
         OPENDATASOURCE(server).dbo.table1
     WHERE 
         qux = 1 AND quux = 'A' AND corge = 2) tab1
JOIN
    (SELECT 
         foo, 
         bar, 
         baz, 
         bam
     FROM 
         OPENDATASOURCE(server).dbo.table1
     WHERE 
         qux = 1 AND quux = 'B' AND corge = 2) tab2 ON tab1.bar = tab2.bar
                                                    AND tab1.baz = tab2.baz
                                                    AND tab1.foo = tab2.foo

问题在于这些表中的每个表都有几列,但有数千万条记录。这造成了一种独特的情况,即索引不能充分提高性能(上面的查询使用了table1中的每一行)。

我注意到的是,这些表调用仅在一个或两个较小的方面发生变化,例如本例中的quux,并且它们没有主键需要使用的行多于不必要的行,这对索引没有帮助似乎多余。

除了简单的索引编制之外,还有其他方法可以改善性能吗?我愿意更改基础表并创建孤立表。

2 个答案:

答案 0 :(得分:1)

您可以改善的一个性能问题是跨服务器加入。 OPENROWSET,链接的服务器等会发生这种情况。

减轻它的最简单方法是将数据从远程数据源拉入临时表或登台表。这会将数据本地存储在tempdb中。然后,加入临时表。 SQL Server会自动为这些表创建统计信息,这将大大提高您的性能,而且数据是本地数据,但您也可以添加索引以加快连接速度。

答案 1 :(得分:0)

按索引,您需要在源服务器上使用它:

CREATE NONCLUSTERED INDEX IX_NC_table1_bar_baz_INC_FILT ON dbo.table1(bar, baz)
INCLUDE(foo, bam)
WHERE qux = 1 AND quux = 'B' AND corge = 2;

然后,您可以在其顶部创建索引视图,并在源框中使用RANK()计算创建SP。 一旦拥有了所有这些,就可以调用它来消耗大部分预先计算的数据+现金计划。

更新:

因此,在目标框中创建的SP应该是上述select语句的精确副本。您必须在目标服务器上创建它,以便SP执行计划将被创建和缓存,并且您的统计信息将用于更好的资源优化,从而带来总体上更好的性能。 一旦有了该SP,就可以像这样调用它:

DECLARE @SP_SQL VARCHAR(128);
SET @SP_SQL = 'EXEC [DB].[Schema].[SP_Name]'; --> from the target
EXEC (@SP_SQL) AT [Target_Server];
相关问题