优化 select 区别于大型 table
Optimise select distinct from large table
我有一个 table 包含 320,071,712 条记录,我目前正在处理的报告可以按日期过滤记录,之后记录数下降到 145,878,852。不同记录的数量为 107,311,357。
select count(*)
from [BroadcastOpens] with (nolock)
where [OpenTimeUtc] >= @StartDate
and [OpenTimeUtc] <@EndDate
最耗时的过程是SELECT DISTINCT,到运行用了大约40分钟。
SELECT DISTINCT [SubscriberId],[OpenTimeUtc]
FROM [BroadcastOpens] WITH (nolock)
WHERE [OpenTimeUtc] >= @StartDate
AND [OpenTimeUtc] <@EndDate
我已经在此 table 上为 BroadcastId 和 OpenTimeUtc 列创建了两个索引,它们有助于加快进程,但似乎不太重要。
CREATE NONCLUSTERED INDEX [IX_BroadcastOpens_BroadcastId_Temp]
ON [dbo].[BroadcastOpens]([BroadcastId])
CREATE NONCLUSTERED INDEX [IX_BroadcastOpens_OpenTimeUtc_Temp]
ON [dbo].[BroadcastOpens]([OpenTimeUtc])
按照 Martin Smith 的建议,我还在按 [SubscriberId]、[OpenTimeUtc]、[BroadcastId] 分组的 Table BroadcastOpens 上创建了一个索引视图。
CREATE VIEW dbo.vwBroadcastOpensRecords
WITH SCHEMABINDING
AS
SELECT [SubscriberId],[OpenTimeUtc],[BroadcastId], COUNT_BIG(*) as tmp
from [dbo].[BroadcastOpens] group by [SubscriberId],[OpenTimeUtc], [BroadcastId]
CREATE UNIQUE CLUSTERED INDEX CIX_vwBroadcastOpensRecords_Temp ON
vwBroadcastOpensRecords(SubscriberId, OpenTimeUtc,BroadcastId);
这是导致问题的查询步骤
我现在正在测试这两种方法,看看哪一种能产生更好的性能。
1) 对现有的 tsql 查询没有更改,没有创建非聚集索引。 运行 在生产服务器上 ()
2) 不更改现有的 tsql 查询,在 table 上创建了两个非聚集索引。 运行 在登台服务器上
3) 创建一个索引视图,并修改现有的 tsql 查询以使用这个新的索引视图来替换 table
4) 将以上两个table索引合并为一个,重新运行脚本
CREATE NONCLUSTERED INDEX [IX_BroadcastOpens_BroadcastId_Temp] ON [smpro5].[dbo].[BroadcastOpens]([BroadcastId])
GO
CREATE NONCLUSTERED INDEX [IX_BroadcastOpens_OpenTimeUtc_Temp] ON [smpro5].[dbo].[BroadcastOpens]([OpenTimeUtc])
GO
DROP INDEX IX_BroadcastOpens_BroadcastId_Temp ON [smpro5].[dbo].[BroadcastOpens]
GO
DROP INDEX IX_BroadcastOpens_OpenTimeUtc_Temp ON [smpro5].[dbo].[BroadcastOpens]
GO
CREATE NONCLUSTERED INDEX [IX_BroadcastOpens_OpenTimeUtc_BroadcastId_Temp] ON [dbo].[BroadcastOpens]([OpenTimeUtc], [BroadcastId]);
GO
只是想知道。 Table BroadcastOpens table 不断更新,这是否会影响我创建的索引视图?
采纳任何关于如何改进此查询的建议!
感谢 HABO 和 Martin Smith 的宝贵帮助!
注意:当涉及到索引视图时,不要忘记使用 WITH (NOEXPAND)!
有两个单独的索引对这个查询不是很有帮助。拥有覆盖索引应该可以解决您的问题:
CREATE NONCLUSTERED INDEX [IX_BroadcastOpens_OpenTimeUtc_BroadcastId_Temp]
ON [dbo].[BroadcastOpens]([OpenTimeUtc], [BroadcastId]);
1) 删除了所有 DISTINCT 关键字
2) 在 BroadcastOpens Table 上创建非聚集索引以加快搜索速度
3) 可能会或可能不会创建索引视图
结果:花费的时间从 42:32 分钟减少到 38:15 分钟。
我有一个 table 包含 320,071,712 条记录,我目前正在处理的报告可以按日期过滤记录,之后记录数下降到 145,878,852。不同记录的数量为 107,311,357。
select count(*)
from [BroadcastOpens] with (nolock)
where [OpenTimeUtc] >= @StartDate
and [OpenTimeUtc] <@EndDate
最耗时的过程是SELECT DISTINCT,到运行用了大约40分钟。
SELECT DISTINCT [SubscriberId],[OpenTimeUtc]
FROM [BroadcastOpens] WITH (nolock)
WHERE [OpenTimeUtc] >= @StartDate
AND [OpenTimeUtc] <@EndDate
我已经在此 table 上为 BroadcastId 和 OpenTimeUtc 列创建了两个索引,它们有助于加快进程,但似乎不太重要。
CREATE NONCLUSTERED INDEX [IX_BroadcastOpens_BroadcastId_Temp]
ON [dbo].[BroadcastOpens]([BroadcastId])
CREATE NONCLUSTERED INDEX [IX_BroadcastOpens_OpenTimeUtc_Temp]
ON [dbo].[BroadcastOpens]([OpenTimeUtc])
按照 Martin Smith 的建议,我还在按 [SubscriberId]、[OpenTimeUtc]、[BroadcastId] 分组的 Table BroadcastOpens 上创建了一个索引视图。
CREATE VIEW dbo.vwBroadcastOpensRecords
WITH SCHEMABINDING
AS
SELECT [SubscriberId],[OpenTimeUtc],[BroadcastId], COUNT_BIG(*) as tmp
from [dbo].[BroadcastOpens] group by [SubscriberId],[OpenTimeUtc], [BroadcastId]
CREATE UNIQUE CLUSTERED INDEX CIX_vwBroadcastOpensRecords_Temp ON
vwBroadcastOpensRecords(SubscriberId, OpenTimeUtc,BroadcastId);
这是导致问题的查询步骤
我现在正在测试这两种方法,看看哪一种能产生更好的性能。
1) 对现有的 tsql 查询没有更改,没有创建非聚集索引。 运行 在生产服务器上 ()
2) 不更改现有的 tsql 查询,在 table 上创建了两个非聚集索引。 运行 在登台服务器上
3) 创建一个索引视图,并修改现有的 tsql 查询以使用这个新的索引视图来替换 table
4) 将以上两个table索引合并为一个,重新运行脚本
CREATE NONCLUSTERED INDEX [IX_BroadcastOpens_BroadcastId_Temp] ON [smpro5].[dbo].[BroadcastOpens]([BroadcastId])
GO
CREATE NONCLUSTERED INDEX [IX_BroadcastOpens_OpenTimeUtc_Temp] ON [smpro5].[dbo].[BroadcastOpens]([OpenTimeUtc])
GO
DROP INDEX IX_BroadcastOpens_BroadcastId_Temp ON [smpro5].[dbo].[BroadcastOpens]
GO
DROP INDEX IX_BroadcastOpens_OpenTimeUtc_Temp ON [smpro5].[dbo].[BroadcastOpens]
GO
CREATE NONCLUSTERED INDEX [IX_BroadcastOpens_OpenTimeUtc_BroadcastId_Temp] ON [dbo].[BroadcastOpens]([OpenTimeUtc], [BroadcastId]);
GO
只是想知道。 Table BroadcastOpens table 不断更新,这是否会影响我创建的索引视图?
采纳任何关于如何改进此查询的建议!
感谢 HABO 和 Martin Smith 的宝贵帮助!
注意:当涉及到索引视图时,不要忘记使用 WITH (NOEXPAND)!
有两个单独的索引对这个查询不是很有帮助。拥有覆盖索引应该可以解决您的问题:
CREATE NONCLUSTERED INDEX [IX_BroadcastOpens_OpenTimeUtc_BroadcastId_Temp]
ON [dbo].[BroadcastOpens]([OpenTimeUtc], [BroadcastId]);
1) 删除了所有 DISTINCT 关键字 2) 在 BroadcastOpens Table 上创建非聚集索引以加快搜索速度 3) 可能会或可能不会创建索引视图
结果:花费的时间从 42:32 分钟减少到 38:15 分钟。