2011-07-26 40 views
14

使用显式创建表语句和加载数据与选择到数据库之间有任何性能差异。这个例子只显示了2列,但问题是适用于使用非常大的表格。下面的例子也使用临时表,但我想知道使用常规表的效果。尽管如此,我认为它们会是相同的。使用显式创建表语句创建表与选择到

临时表的场景:

--- Explicitly creating temp table first and then loading. 
create table #test1 (id int, name varchar(100)) 
insert into #test1 (id, name) select id, name from #bigTable 

--- Creating temp table by selecting into. 
select id,name into #test2 from #bigTable 

或常规表:

--- Explicitly creating table first and then loading. 
create table test1 (id int, name varchar(100)) 
insert into test1 (id, name) select id, name from #bigTable 

--- Creating table by selecting into. 
select id,name into test2 from bigTable 

什么是大家对这个想法?我认为明确创建表和加载必须比select into into更好的性能必须评估语句中的表达式才能创建表。

我们的组织通常会明确创建临时表作为标准做法,我们想知道什么都认为实际上是最佳实践。

http://msdn.microsoft.com/en-us/library/ms188029.aspx

+0

我没有时间检查,但您可能会发现这是重新编译的原因。这个潜在的开销是否大于Adam Houldsworth所暗示的其他好处,我会留给你或其他人去找出:) – MatBailie

+0

你检查过两种变种的执行计划吗?你是否真的计时了他们,看看有没有可衡量的差异? – HLGEM

+0

我已经尝试了两个更早,但不是在一大组数据。我现在没有试图解决任何性能问题,我很好奇每种插入方法的优缺点... – mservidio

回答

5

CREATE TABLE可以在插入数据之前更好地控制表格的定义,如NOT NULL,约束条件等等,您无法使用的东西SELECT INTO

SELECT INTO是一个最小化日志操作,但在某些情况下,INSERT..SELECT也可以被最小化记录。
The Data Loading Performance Guide,尤其是部分:总结最小测井条件

简而言之,如果你不关心约束条件等(例如你想快速创建表的副本),那么SELECT..INTO的好处就是代码较短。
否则,您应该使用其他方式,并且您仍然可以将其记录为最低限度。

+0

感谢您的链接,看起来像一个伟大的文章。将来必须给它一个阅读。 – mservidio

2

选择到已登录的好处(没有做多),这样的表现实际上是在大多数情况下更好。但是,如果表存在,它就会出错,并且不会构建索引或约束等东西,只是列。

取决于你需要它。我知道我们有一些动作,SELECT ... INTO然后重命名,因为它比更新旧表更快(显然有很多绒毛重建表对象等)。

请记住,我们的用法不适用于临时表,我刚刚在您的问题中注意到这种情况。

对于具有索引的表,insert into必须将索引作为插入过程的一部分进行维护。然后有其他表格对象可以导致更多的处理,例如触发器。在select into的情况下,就我所知,表格是裸露的,因此初始插入表现非常好。加上事务日志的影响是最小的(在你的问题中提到这个链接)。

这实际上取决于临时表的使用情况,我认为它们将会相对短暂,所以select into后跟截断/ drop可以很好地工作。如果他们有更长的跨度,但以其他方式抛弃,再次选择,然后最终下降可以工作。

如果他们需要在创建之后生存很长时间并且不会丢弃,那么除了初始创建和插入数据(这将会很快)之外,您将随后插入数据并返回原点 - 您最好只调整表格以接受快速插入,例如通过使用最小索引或先禁用索引并重新启用插入后插入。

在大型表碰巧有聚簇索引的情况下,我也看到了一种技巧,插入数据时,聚集索引将插入数据。

+0

我会修改这个问题,我想知道不管表类型 – mservidio

+0

你知道如果'SELECT ... INTO#temp'会导致重新编译吗? – MatBailie

+0

@Dems不确定,对不起。 –

0

在我的情况下,执行显式的CREATE,然后执行INSERT INTO在实际运行时间和优化器的估计成本方面明显更好。

我的临时表不是很大(8行),但其中一个值是计算的字符串值。在某些情况下,此临时表与具有数十万行的结果集结合在一起。我相信当我为我的临时表做一个SELECT INTO时,它并没有为计算出来的值选择最佳的数据类型。所以,当我使用CREATE显式定义列数据类型时,SQL Server能够更高效地执行连接。当然,这个效应被夸大了,因为涉及到很多行。

因此,在某些情况下,特别是当您的某个列是计算值时,CREATE和INSERT可能是更好的选择。你的里程可能会有所不同,所以一定要进行一些测试!