我正在尝试将内存数据行插入到SQL Server Express 2005上的表中。它在我看来非常缓慢地运行 - 每1000行插入大约5秒。我只是使用基本的“INSERT INTO”命令。缓慢不依赖于表数据 - 对于具有一个int列且没有索引的表,它仍然很慢。它与我的软件无关 - 它在Management Studio的循环中运行缓慢。没有其他东西可以同时访问数据库。在3Ghz Xeon(我知道的旧版本)上,执行大约需要10秒钟:
declare @i int
set @i = 0
set nocount on
while @i < 2000
begin
insert into testdb(testcolumn)
values (1)
set @i = @i + 1
end
是否有更好的方法来插入批量内存数据而不是在INSERT上循环?或者我应该在SQL Server中更改一些配置?
答案 0 :(得分:24)
您在自己的交易中执行每个插入。
SQL Server
中的开始和提交交易非常。
将所有内容封装到一个事务块中:
declare @i int
set @i = 0
set nocount on
BEGIN TRANSACTION
while @i < 2000
begin
insert into testdb(testcolumn)
values (1)
set @i = @i + 1
end
COMMIT
要生成示例数据,您可以使用递归CTE
:
WITH q (num) AS
(
SELECT 1
UNION ALL
SELECT num + 1
FROM q
WHERE num < 2000
)
INSERT
INTO testdb(testcolumn)
SELECT 1
FROM q
OPTION (MAXRECURSION 0)
,会更快。
答案 1 :(得分:7)
1)日志刷新提交。每个事务都必须确保在提交返回之前将日志刷新到磁盘。每个INSERT语句都是一个隐式事务。批量提交:
declare @i int
set @i = 0
set nocount on
begin transaction
while @i < 2000
begin
insert into testdb(testcolumn)
values (1)
set @i = @i + 1
if (@i % 1000 = 0)
begin
commit;
begin transaction;
end
end
commit
2)慢盘。检查Avg. Disk sec/Transfer性能计数器,查看您的数据和日志磁盘 3)对于许多指数(不太可能在测试表上)。每个指数几乎与插入物的“表格”一样昂贵 4)触发(再次,不太可能)
最终,衡量。如果您不知道从哪里开始,请遵循Troubleshooting Performance Problems in SQL Server 2005等白皮书的指导原则。
答案 2 :(得分:5)
您有足够的工具/技术可以从这类工作量中获得更高的性能。
答案 3 :(得分:3)
除了索引之外,如果您的实际场景与您的示例相同,您可以执行基于集合的方法来插入2000条记录,如下所示:
INSERT testdb(testcolumn)
SELECT 1
FROM master..spt_values
WHERE number BETWEEN 1 AND 2000
答案 4 :(得分:1)
插入速度由以下因素驱动:
如果有任何兴趣,我会在我的书(Ultra-Fast ASP.NET)中详细介绍,包括基准和示例代码。
答案 5 :(得分:0)
拥有聚簇索引(通常是主键)实际上会提高插入速度,因此请确认您拥有其中一个。如果您可以同时拥有所有数据并将其插入表中,则对表运行1000个事务并不是最快的方法(这可以通过使用sql server 2008中的表值参数或2005年的xml参数来实现)。
答案 6 :(得分:0)
我会google到“SQL Server Tuning”......有很多关于这个主题的书。这是一件非常难以解决的事情,因为有许多因素影响速度,从查询语法到分配给服务器的RAM,到分配的RAM(你分配RAM的SQL Server的一部分)的比例,到RAID阵列配置,和许多其他因素。您可以为插入/更新(OLTP)或查询(数据仓库类型的东西)优化数据库服务器。换句话说,不要指望对此有一个简单的答案,即使你的问题看起来很简单。
这就是您拥有数据库服务器管理员的原因。
或者,如果时间对您来说不是很重要,那么您可以尽可能地解决服务器端问题并尽可能优化客户端代码。
我会将准备好的陈述和交易作为开始优化的一种方式。然后看一下索引(如果这是一组经常不会发生的插入,我会考虑删除索引,进行导入,再次创建索引)。