2012-03-18 141 views
1

是否有人能够提供有关SQL Server能够进行哪些优化的信息?我使用的是2005年的标准版,有时也和2008年一起工作。 2008能够执行2005年不能查询的优化吗?SQL Server优化

有时候我会运行一个查询,这将需要很长时间没有明显的原因,我必须用不同的方法重写它。 (CTE而不是子查询等)我想提前知道在开始使用SQL服务器之前SQL服务器是否会为查询提供最佳或接近可选的性能。

加入到子查询

select ... from tbl1 left join(
    select ... from tbl2 group by ... 
) as subQ on t1.pk = subQ.fk 
where t1.pk between 50 and 100 

如果我加入一个表的子查询同上,结果集进行过滤,我可以期待WHERE子句中过滤下来所有 SQL服务器进行传播相关的子查询?编译器在确定结果集的哪些部分最终将用于最终输出中有多好?

很多组列由

子查询与分组依据,往往可以写成一个直线上升加盟,但随后被

select tbl1.pk,b,c,d,e,f,g, sum(tbl2.h) from tbl1 
inner join tbl2 on tbl1.pk = tbl2.fk 
inner join tbl3 on tbl1.fk = tbl3.pk 
group by tbl1.pk, tbl1.b, tbl3.c, tbl3.d, tbl3.e, tbl3.f, tbl3.g 

每个引用组中的许多列是必要的除表3中的一行外,表1中的行将与表2中的多行相匹配。(注意与表3的pk的连接)由于此原因,组中除tbl1.pk之外的所有列都是多余的。但是,SQL要求无论如何都要在组中使用它们。现在优化器应该只是在表1的主键上进行排序,以便聚合表2中的行。它会这样做,还是会不必要地对组中的整个列集进行排序和比较?如前所述,另一种方法是将表2聚合到子查询中,然后再回到表1和表3中。这是否有所不同?

回答

1

是2008能够进行额外的优化。

其中一个指标是sys.dm_exec_query_transformation_stats在我的2008实例上有390个可能的转换,在我的2005实例上有380个转换(关于此DMV的一些解释here)。

一般来说,差异是进化改善,但不是显着。我从自己的经历中发现,在Connect上报告次要性能问题时,他们倾向于修复下一个版本,而不是回溯到以前的版本(e.g. 1,e.g. 2

我知道有几个领域在2008年有所改进正在处理partitioned tables,当使用OPTION (RECOMPILE)计划时,查询计划为dynamic search conditions,在Views中使用predicate pushing

关于您提出的具体情况,您需要检查两个版本中的执行计划,以了解您是否可以辨别策略中的任何差异。

+0

谓词推送示例指示问题出现在视图中,但与表值函数不同。在这种情况下,使用(非索引)视图是否有意义?表函数似乎没有任何缺点。 – Trent 2012-03-20 13:29:11

+0

@Trent - 您无法在TVF或呼叫端创建触发功能(例如'NEWID()')。如果你不需要那些,那么不需要。不AFAIK。 – 2012-03-20 13:38:31

2

“有时我会运行一个查询,它会花费大量的时间没有明显的原因” - 我会调查重写查询之前的实际原因。

通常情况下,由于过期的统计信息或索引需要重新构建或缺少索引,因此原因是不适当的缓存查询计划。

这是标准基准:Slow in the Application, Fast in SSMS?

至于你的发言:“我想知道提前SQL服务器是否要给我最佳的或接近可选的性能从查询之前,我开始使用它“ - 最佳往往是相对的。 SQL Server使用统计信息和基于成本的优化器来确定查询计划。通常,您必须针对正常运行的查询工作负载进行优化,而不是针对单个查询。该SQL Server 2008有

一种优化是优化即席查询工作负载(如奥姆斯产生的那些)的能力:Plan cache and optimizing for adhoc workloads

[BTW:对于SQL私人MVP排行榜上谈到,即使服务器,优化器在特定情况下的运行方式并不总是受到产品团队的推崇。有可能推断出一些,但它可以在更新之间变化。]