优化选择与大表不同

时间:2015-02-16 21:35:50

标签: tsql query-optimization

我有一个包含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

我在此表上为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);

这是导致问题的查询中的步骤 enter image description here

我现在正在测试两种方法,看看哪种方法能产生更好的效果。

1)没有更改现有的tsql查询,也没有创建非聚集索引。在生产服务器上运行()

enter image description here

2)对现有的tsql查询没有变化,在表上创建了两个非聚簇索引。在登台服务器上运行

enter image description here

3)创建一个索引视图,并修改现有的tsql查询以使用这个新的索引视图来替换表

enter image description here

4)将两个表索引合并为一个,重新运行该脚本 enter image description here

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表会不断更新,这是否会引起我创建的索引视图的关注?

有关如何改进此查询的任何建议都是适当的!

感谢HABO和Martin Smith的宝贵帮助!

注意:在索引视图方面,不要忘记使用WITH(NOEXPAND)!

2 个答案:

答案 0 :(得分:0)

拥有两个单独的索引对此查询不是很有帮助。覆盖索引应该可以解决您的问题:

CREATE NONCLUSTERED INDEX [IX_BroadcastOpens_OpenTimeUtc_BroadcastId_Temp] 
ON [dbo].[BroadcastOpens]([OpenTimeUtc], [BroadcastId]);

答案 1 :(得分:0)

1)删除了所有DISTINCT关键字 2)在BroadcastOpens表上创建非聚簇索引以加速搜索 3)5月或5月不能创建索引视图

结果:时间从42:32分钟缩短到38:15分钟。