调整Select语句以获得更快的结果

时间:2013-12-09 10:13:34

标签: sql-server performance indexing

我已经从这个网站中受益了很长时间了。这是我在网站上的第一个问题。它涉及性能调整报告查询。在这里。 1.

SELECT Count(b1.primkey) 
from tableA b1 --WITH (NOLOCK) 
join tableA b2 --WITH (NOLOCK) 
on b1.email = b2.email
and DateDiff(day, b2.BookedDate , b1.BookedDate) > 1

tableA有大约700万行。电子邮件是varchar(100)字段。 Bookeddate是一个日期时间字段。 primkey是一个主键列,它是一个int。

我编写此查询的目的是找出具有相同电子邮件ID但迟到一天的计数条目。此查询大约需要45分钟才能运行。我真的想减少执行所需的时间。

由于这是用于报告,我徒劳地尝试使用--WITH (NOLOCK)选项来改善阅读时间。我在tableA上有一个列存储索引,我知道SQL优化器正在使用它 - 可以在执行计划中看到。我正在使用SQL Server 2012.

  1. 在这种情况下,有人可以告诉我,还有什么会更好?在电子邮件上使用非聚集索引或在tableA上使用非聚簇列存储索引?
  2. 请帮帮我。

3 个答案:

答案 0 :(得分:0)

这里有3个选项:

  1. 至少为较大的表在email字段上创建聚簇索引。 但我想在这些表上运行其他查询,并且 其他字段需要聚集索引
  2. 将电子邮件移至另一个表,并将电子邮件ID存储在TableA和 表B;在int字段上的连接比在varchar上快得多 字段
  3. 在包含列BookedDate的电子邮件字段上创建索引(没有 需要包含primkey,你可以指望另一个字段,或count(*)。代码:create index idx_email on TableA include(BoodedDate)
  4. 我认为第三个选项是你应该选择的选项。没有太多工作要做,而且会有很大的性能提升。唯一的问题是varchar字段上的索引会占用大量空间并影响插入/更新操作;但是你说这是一个报告数据库,所以我认为你可以允许这样做。

答案 1 :(得分:0)

您的查询相对复杂。实际上,您正在连接两个表,这些表在一​​个非唯一的列上各有700万条记录。

以下查询如何:

select Email
from TableA
group by Email
having MAX(BookedDate) > MIN(BookedDate) + 1

还要确保您拥有Email和BookedDate的索引。

希望这有帮助。

答案 2 :(得分:-1)

希望您的查询输出正确。当您使用前500时,它会为您提供正确的记录。

使用任何一种情况需要多长时间。

我也希望你知道Nonclustered columnstore index。 它仅在Readonly表中使用。这意味着您无法在该表上插入/更新/删除。

如果它不是只读的,那么您可以在电子邮件和日期列上创建非聚集索引