2013-12-09 37 views
1

我已经从这个网站获益很长一段时间了。这是我在网站上的第一个问题。这是关于性能调整报告查询。在这里。 1.调整Select语句以获得更快的结果

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上使用非聚簇列索引?

请帮帮我。

+1

请发布执行计划。如果您还无法在此处上传图片,则可以在外部托管它。或者将.sqlplan文件上传到某处。有多少个不同的电子邮件地址?考虑一下:如果2013-01-01日期的某个电子邮件有10条记录,2013-01-02日期的同一电子邮件有10条记录,那么这将记录为100(而不是10)。你知道吗? – usr

回答

0

您所查询的是相对复杂的。你基本上是加入了两个表,每个表有700万条记录,这些记录不是唯一的。

如何下面的查询代替:

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

另外,还要确保你有电子邮件和BookedDate的索引。

希望这会有所帮助。

+0

这是一个很好的。谢谢。我会试试看 – user3082259

0

你有3个选择这里:

  1. 至少对于较大的表创建于email场聚集索引。需要在其他领域
  2. 邮件转移到另一个表,并存储电子邮件ID在表A和表B 但我想有这些表上运行的其他查询,并 聚集索引;加入对INT领域会比在VARCHAR 领域快得多
  3. 与包含的列上创建电子邮件字段的索引BookedDate(无 需要包括primkey,你可以指望另一个字段,或COUNT(*)代码:create index idx_email on TableA include(BoodedDate)

我觉得第三个选择是你应该去的,没有太多的工作要做,并且会有很大的性能提升,唯一的问题是varchar字段上的索引会占用很多空间,影响插入/更新操作;但是你说这是一个报告数据库,所以我认为你可以允许。

+1

700万行表如何导致45分钟的运行时间?即使是堆表应该更快。还有一件事我们还不知道。 SQL Server甚至可以在查询执行期间构建临时索引。 – usr

+0

@us同意,但问题在于调整select语句,我们可以立即回答。 –

-1

希望你的查询ou输入是正确的。当你使用500强时,它会给你正确的记录。

当您使用任一条件时需要多少次。

我也希望您知道非聚集列存储索引。 它仅在Readonly表中使用,这意味着您无法在该表上插入/更新/删除。

如果没有,那么只读您可以创建电子邮件和日期列的非聚集索引都

相关问题