0

我是这方面的初学者,所以希望你能提供帮助。我在 SQL Server 2008R2 中工作,并且有一个由四个表组成的视图,这些表全部连接在一起:

SELECT DISTINCT ad.award_id,
                bl.funding_id,
                bl.budget_line,
                dd4.monthnumberofyear AS month,
                dd4.yearcalendar      AS year,
                CASE
                  WHEN frb.full_value IS NULL THEN '0'
                  ELSE frb.full_value
                END                   AS Expenditure_value,
                bl.budget_id,
                frb.accode,
                'Actual'              AS Type
FROM   dw.dbo.dimdate5 AS dd4
       LEFT OUTER JOIN dbo.award_data AS ad
                    ON dd4.fulldate BETWEEN ad.usethisstartdate AND
                                            ad.usethisenddate
       LEFT OUTER JOIN dbo.budget_line AS bl
                    ON bl.award_id = ad.award_id
       LEFT OUTER JOIN dw.dbo.fctresearchbalances AS frb
                    ON frb.el3 = bl.award_id
                       AND frb.element4groupidnew = bl.budget_line
                       AND dd4.yearfiscal = frb.yr
                       AND dd4.monthnumberfiscal = frb.period  

该视图有 9 列和 150 万行,并且还在不断增长。从此视图中选择 * 对所有行都需要 20 分钟。我在加入的表中的字段上添加了索引,并将其改进为 10 分钟。我的问题是我还能做些什么来让选择运行得更快?

非常感谢,紫罗兰。

4

4 回答 4

0
    SELECT DISTINCT --#1 - potential bottleneck 
                    ad.award_id
                ,   bl.funding_id
                ,   bl.budget_line
                ,   [month] = dd4.monthnumberofyear 
                ,   [year] = dd4.yearcalendar 
                ,   Expenditure_value = ISNULL(frb.full_value, '0')
                ,   bl.budget_id
                ,   frb.accode
                ,   [type] = 'Actual' 
    FROM dbo.dimdate5 dd4
    LEFT JOIN dbo.award_data ad ON dd4.fulldate BETWEEN ad.usethisstartdate AND ad.usethisenddate
    LEFT JOIN dbo.budget_line bl ON bl.award_id = ad.award_id
    LEFT JOIN dbo.fctresearchbalances frb ON frb.el3 = bl.award_id --#2 - join by multiple columns
        AND frb.element4groupidnew = bl.budget_line 
        AND dd4.yearfiscal = frb.yr 
        AND dd4.monthnumberfiscal = frb.period
于 2013-09-27T11:13:49.300 回答
0

1-您可以使用存储过程来进行缓冲区缓存。2-您可以使用索引视图,这意味着在模式绑定视图上创建索引。3-您可以在连接中使用查询提示来命令查询优化器使用特殊类型的连接。4-您可以使用表分区。

于 2013-09-27T10:11:06.607 回答
0

CASE 语句可以替换为

COALESCE(frb.full_value,'0') AS Expenditure_value

如果没有更多信息,就不可能准确地告诉你出了什么问题,而只是给你一些指示。当您有这么多 LEFT JOINS 时,连接的顺序会有所不同。您是否有标准索引或包含列的覆盖索引?如果您没有覆盖索引,则连接中的主键很重要。在连接条件中包含所有主键列将加快查询速度。

然后查看您的数据 - 您是否需要基于这些表之间的外键的所有这些 LEFT JOINS?根据您的键,LEFT JOIN 可能等同于 INNER JOIN。有了所有这些 LEFT JOINS,DISTINCT 真的有用吗?

你有多少内存?如果您有 8GB+,那么 150 万行对于 SQL Server 来说不算什么。您需要优化这些连接。

于 2013-09-27T12:57:21.843 回答
0

尝试摆脱 case 语句。

如果您有 150 万行,如果您对这些行的聚合而不是整个集合感兴趣,您可能希望先对 fctResearchBalances 中的行求和,然后再进行连接。

(在没有看到访问计划的情况下,很难确定您还能从中受益什么。)

于 2013-09-27T10:05:47.663 回答