为什么SQL服务器插入这么慢?

Pet*_*ter 3 sql sql-server-2005

我正在尝试将内存数据行插入到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  
Run Code Online (Sandbox Code Playgroud)

是否有更好的方法来插入大容量内存数据而不是在INSERT上循环?或者我应该在SQL Server中更改一些配置?

Qua*_*noi 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
Run Code Online (Sandbox Code Playgroud)

要生成样本数据,可以使用递归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)
Run Code Online (Sandbox Code Playgroud)

,这会更快.

  • 在我自己尝试之前,我没有意识到这有多大区别 - 使用海报的代码在1.3秒内包含在交易中的200,000行.没有交易,花了47秒. (3认同)

Rem*_*anu 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
Run Code Online (Sandbox Code Playgroud)

2)慢盘.检查平均值.磁盘秒/传输性能计数器,用于存储数据和日志磁盘.
3)对于许多指数(不太可能在测试表上).每个索引几乎与插入的"表"一样昂贵.
4)触发(再次,不太可能)

最终,衡量.如果您不知道从哪里开始,请遵循白皮书的指导,如SQL Server 2005中的性能问题疑难解答.


Cha*_*had 5

您有大量的工具/技术可以从这种类型的工作负载中获得更高的性能.

  1. 如果适当,您可以批量加载任何内容.有些事你不能.需要对记录运行验证,目标表有可空列...
  2. 考虑将复杂的数据仓库/ ETL操作移动到没有事务日志记录(也称为简单模式)的登台数据库.这将大大提高性能.然后批量/批量处理数据到目标系统.
  3. 批量非批量装入插入操作.提交每n条记录从1,000开始,并从那里进行性能调整.
  4. 提高磁盘存储速度.更快更快的磁盘比更大和更慢更好.我工作的最后一个db性能调优项目我们从本地磁盘10,000 RPM转移到SAN然后再回到服务器上的固态磁盘进行某些操作.固态绝对是岩石!但是很贵.
  5. 使用force,um性能调优工具为Sql Server找到不太明显的瓶颈.有时,最佳操作方法可能是根据与表大小相比插入/删除的记录百分比来删除和重建索引; 某些操作期间禁用触发器; 并修改数据块中记录的稀疏性.