哪个最快,1x 插入 512 行,4x 插入 128 行,或 512x 插入 1 行

Which would be fastest, 1x insert 512 rows, 4x insert 128 rows, or 512x insert 1 rows

提问人:J-Dizzle 提问时间:10/8/2014 更新时间:10/12/2014 访问量:88

问:

我有 512 行要插入到数据库中。我想知道提交多个插入物是否比提交一个大插入物有什么优势。例如

1x 512 行插入 --

INSERT INTO mydb.mytable (id, phonenumber)
VALUES (1, 555-555-5555) , (2, 555-555-5555) , (3, 555-555-5555), //repeat to id = 512

VS 4x 128 行插入

INSERT INTO mydb.mytable (id, phonenumber)
VALUES (1, 555-555-5555) , (2, 555-555-5555) , (3, 555-555-5555), //repeat to id = 128
INSERT INTO mydb.mytable (id, phonenumber)
VALUES (129, 555-555-5555) , (130, 555-555-5555) , (131, 555-555-5555), //repeat to id = 256, then next 128, then next 128.

VS 512x 1 行插件

INSERT INTO mydb.mytable (id, phonenumber)
VALUES (1, 555-555-5555)
INSERT INTO mydb.mytable (id, phonenumber)
VALUES (2, 555-555-5555) // repeat until id = 512

还有一个关于测试的问题,如果我把它设置为一个测试 - 假设我做第一种方法,一个大的 512 行插入。这需要 0.5 秒。然后下一次需要 0.3 秒 -- 我认为会发生的这种缓存,就像编程语言执行两次相同的操作时一样,在 sql 中发生吗?(因此,是否有必要为每种方法获得良好的测试结果平均值?

在进行超大刀片(例如五十万次)时,我还应该考虑哪些其他因素?如果发送到数据库的数据包太大,它永远不会接收或执行查询,这是真的吗 -- 我甚至会因为进行非常大的插入而遇到麻烦吗?

SQL 数据库 与语言无关 查询性能

评论


答:

5赞 Joe Baker 10/8/2014 #1

我的答案是假设 SQL Server;我怀疑我所说的将适用于其他 SQL 引擎。

任何 SQL Server 查询的大部分开销都是执行计划的开发。如果将其作为单个插入执行此操作,则必须制定一 (1) 次执行计划;如果分别执行 512 次插入,则必须制定 512 次执行计划。因此,单次插入的开销要小得多。

我不会惊讶地发现引擎发现了你不知道做、不想做或做不到的其他效率。但是,如果只是执行计划的节省,那么在一次插入中仍然值得这样做。

评论

0赞 Joe Baker 10/8/2014
哦。。。对于五十万个插入物,答案是一样的,只是更多。你可能会发现在逻辑上有必要将其分解一些(在某些时候,记忆可能会成为一个问题);但一般来说,你越少分解它越好。
0赞 J-Dizzle 10/8/2014
关于这个制定执行计划的主题:我对执行计划的了解是有限的,但是,在做 512 1 行插入时,执行计划会是一样的吗?如果是这样,这将使我相信它会被缓存,并且对此进行测试将需要一组良好的平均值,因为插入所需的时间会越来越少
0赞 Joe Baker 10/8/2014
最后一个想法 -- 您是通过查询管理器还是从代码中执行此操作?如果来自代码,那么有一种更好的方法来处理它,即使用 SqlBulkCopy。
0赞 Joe Baker 10/8/2014
我从未见过任何证据表明它缓存了执行计划;我尝试尽可能使用存储过程,因为它将生成和存储执行计划(可能是您感兴趣的解决方案)。
1赞 J-Dizzle 10/8/2014
我实际上正在做的是通过 PHP,如果你愿意,你可以谈谈这个问题,但问题主要是关于数据库引擎 itself.is SqlBulkCopy 一个 SQL 服务器的东西?我认为在像 mysql 这样的引擎中,带有变量的存储过程几乎是最好的方法。我很高兴你回答了第一个问题,你回答得很好
4赞 Bill Karwin 10/8/2014 #2

答案可能会因您使用的 RDBMS 产品而异。不能以与实现无关的方式制定细粒度的优化计划。

但是你可以进行广泛的观察,例如,最好删除循环不变代码

如果对同一个表进行多个 INSERT 循环,则可以做出有根据的猜测,即循环不变量类似于 SQL 解析和查询执行规划。某些优化器实现可能会缓存查询执行计划,而其他一些实现则不会。

因此,我们可以假设 512 行的单个 INSERT 可能更有效。同样,在给定的实施中,您的里程可能会有所不同。

至于加载数百万行,您真的应该考虑批量加载工具。大多数RDBMS品牌都有自己的特殊工具或非标准SQL语句来提供高效的批量加载,这比任何基于INSERT的解决方案都快一个数量级。

因此,您只是浪费了时间担心单个 INSERT 是否比多个 INSERT 更有效率。

评论

0赞 J-Dizzle 10/8/2014
虽然这是最快的,但以我的实际情况来看,这似乎就像用大锤拍苍蝇一样——因为我接近 10,000 行,而且它实际上并不需要这种效率水平——而且我必须重构太多才能实现这样的解决方案,在一个已经完成的项目中。下次我有一个数据 ETL 需求更大的项目时,我会牢记这些非插入解决方案。
0赞 rossum 10/12/2014 #3

对于许多数据库来说,索引是一种开销。值得测试的是,在执行大型插入之前关闭索引,然后重新索引表是否更快。