插入多个查询是否与单个查询花费相同的时间?

roc*_*ing 3 performance sql-server insert t-sql sql-server-2012

我有一个要求,我必须插入很多行。对于插入,我们像这样使用

insert into emp(name,age) values('abc',12);
Run Code Online (Sandbox Code Playgroud)

这将只插入一行。对于插入多行,我们可以多次编写插入查询或编写具有多个值的单个查询。例如

条件 1

insert into emp(name,age) values('abc1',121);
insert into emp(name,age) values('abc2',122);
insert into emp(name,age) values('abc3',12);
Run Code Online (Sandbox Code Playgroud)

条件2

insert into emp(name,age) values('abc',12),('abc2',122),('abc3',12);
Run Code Online (Sandbox Code Playgroud)

我的问题是上面的(条件 1 和条件 2)都需要时间吗?我猜条件 2 比条件 2 花费的时间少。如果我的猜测是真的,那么原因是什么?

Aar*_*and 6

至少在 SQL Server 中(不能代表你提到的其他 RDBMS,抱歉),单个语句在某种程度上比多个语句更好。当然,您可以使用您的确切陈述和数据自行测试;这里没有人可以用你的具体情况为你测试,你的具体情况可能会以一种或另一种方式倾斜事情。“哪个更快,x 还是 y?” 这里一般不鼓励提问,因为您可以在自己的环境中测试它们,这比我们任何人向您抛出的猜测和逻辑要快得多。特别是当您试图为您列出的所有数据库平台获得答案时 - 没有人是所有这些平台的专家,任何此类答案要么非常有偏见(如这个),要么过于笼统而无用.

但是,一般来说,准备单个语句(并可能根据您的代码和提供者的行为单独发送它们)的开销应该加起来,就像@mustaccio 所说的那样

如果你要寄三封信,你会带着三封信去邮局一次,还是带着一封信去三次?

如果每个小语句都被分解为单个数据包甚至不同的连接,那么在您的场景中尤其如此。同样,我不知道您的提供程序如何工作或您的代码如何发送这些语句 - 如果它是一组可变数量的语句,实际上SQL Server 比单个单语句批处理更难优化,因为 SQL Server在批处理级别进行优化。

请注意,该VALUES()子句具有1,000 个值的任意限制,因此您可能需要根据您拥有的值数量创建多个语句。原因是担心编译时间,正如Paul White 在此处解释的那样另请注意:Oracle 具有相同的限制。

根据Martin Smith 的测试,编译时间至少是最短的,并且相对不变,最多可达 250 多个值。请参阅这些图表(有关详细信息,请参阅他的回答):

编译时间 1

编译时间 2

编译时间 3

如果您使用VALUES()子句,请注意每个变体(即实际值集的数量)都将生成自己的计划,无论您是使用正确的参数化语句还是仅使用内联常量,即使设置了数据库的参数化设置也是如此简单。因此,您可能需要考虑使用optimize for ad hoc workloads服务器设置(此处此处提供了大量信息以防止一次性变体填充计划缓存(无论如何对于大多数系统来说通常是个好主意,除非您受 CPU 限制并且编译成本被证明为过分)。

这个问题的一个更好的答案是使用表值参数 (TVPs),它允许您通过单个参数发送结构化数据集,为您提供一种有效的数据传递方式和一个可以重用的单一计划,而不管传递的值数。这里的问题是我不确定 Java 是否理解这些是什么(在 C# 中,您可以发送,例如,一个 DataTable 作为Structured参数)。


Rem*_*anu 5

对于 SQL Server:两者都不是。

要插入大量行,您应该使用批量插入 API,并努力实现最少记录的插入。

可以使用IRowsetFastLoad(OleDB)、使用批量复制功能(ODBC) 或使用SqlBulkCopy(.Net)来实现批量插入。所有这些 API 的共同点是它们与服务器建立了一个快速插入管道,然后它们开始推送行。这些不是 T-SQL 语句,而是 TDS批量加载消息的实现。在更高的抽象层,您可以使用bcp.exeBULK INSERT语句或启用快速加载选项的SSIS OleDB 目标

第二个可选的改进是实现最少的日志记录。请参阅可以最少记录的操作(批量插入可以,普通插入不能)。有关详细信息,请阅读批量导入中最少日志记录的先决条件

最后,我敦促您花一些时间阅读SQL Server 数据加载性能指南

  • 是的,543 不完全是*很多行*... (2认同)