1

我的任务是优化这个查询:

Declare @sumBalance NUMERIC = (select SUM(CURRENT_BALANCE) as Balance
from dbo.ACCOUNT_DETAILS)
select @sumBalance

我读过聚合函数的最佳解决方案是使用索引视图而不是表。

我用 SCHEMABINDING 创建了视图:

CREATE VIEW dbo.CURRENT_BALANCE_VIEW
WITH SCHEMABINDING
AS
    SELECT id,CURRENT_BALANCE
    FROM dbo.ACCOUNT_DETAILS

之后,我创建了 2 个索引:

身份证第一

 CREATE UNIQUE CLUSTERED INDEX index_ID_VIEW ON dbo.View(ID);

CURRENT_BALANCE 我的第二个专栏的第二个

CREATE NONCLUSTERED INDEX index_CURRENT_BALANCE_VIEW
ON dbo.CURRENT_BALANCE_VIEW(ID);

在这里我遇到了新查询的麻烦:

Declare @sumBalance NUMERIC = (select SUM(CURRENT_BALANCE) as Balance
from dbo.CURRENT_BALANCE_VIEW)
select @sumBalance
  1. 新查询不使用视图

    http://i.stack.imgur.com/jlPEd.png

  2. 不知何故,我的索引被添加到文件夹中Statistics

    看另一个帖子

  3. 我不明白为什么我可以看到索引'index_current_balance',因为表中没有这样的索引

看另一个帖子

PS已经尝试在表中创建索引并且它有所帮助。它使查询的工作速度从 0.2 Es.operator 成本提高到 0.009,但无论如何它必须更快。

pss 抱歉让你点击链接,我的名声不允许我正确地过去图片 =\

psss 使用 SQL Server 2014

pssss 刚刚意识到我不需要对 0-s 求和。期望他们 grom 功能。

提前致谢。

4

2 回答 2

1

这个查询:

Declare @sumBalance NUMERIC = (select SUM(CURRENT_BALANCE) as Balance
                               from dbo.ACCOUNT_DETAILS);
select @sumBalance;

不容易优化。唯一有帮助的索引是:

create index idx_account_details_current_balance on account_details(current_balance);

这是查询的覆盖索引,可用于SUM(). 但是,仍然需要扫描索引才能执行SUM(). 扫描索引应该比扫描表更快,因为它可能要小得多。

SQL Server 2012+ 有一个称为列存储索引的工具,它具有相同的效果。

将索引视图用于聚合函数的建议似乎不是一个好建议。例如,如果上面的查询使用MIN()or MAX(),那么上面的索引应该是查询的最佳索引,它应该运行得很快。

编辑:

你的参考文章很合理。如果您想为此目的创建索引视图,请使用 aggregation创建它。

CREATE VIEW dbo.CURRENT_BALANCE_VIEW
WITH SCHEMABINDING
AS
    SELECT SUM(CURRENT_BALANCE) as bal, COUNT_BIG(CURRENT_BALANCE) as cnt
    FROM dbo.ACCOUNT_DETAILS;

这有点奇怪,因为它返回一行。我认为以下将起作用:

create index idx_account_details on current_balance_view(bal);

如果没有,您可能需要为索引引入一个虚拟列。

然后:

select *
from dbo.current_balance_view;

应该具有预先计算的值。

于 2015-11-13T12:00:19.207 回答
1

如果您使用 SQL-Server 标准版,则必须使用 NOEXPAND-Hint 才能使用视图的索引。

例如:

SELECT *
FROM dbo.CURRENT_BALANCE_VIEW (NOEXPAND);
于 2015-11-13T13:45:22.903 回答