SQL Server插入查询慢(1500rows,4.5sec)

时间:2011-11-11 09:22:30

标签: sql sql-server insert

我正在运行一个本地SQL Server服务器,我正在进行大约1500行的插入查询,这需要很长时间,我真的非常惊讶。 我在这里搜索并搜索了很多想法和解决方案,但仍然发现它的速度慢,我的意思是1500行!

我的问题是,有没有其他方法可以插入这笔金额?是否真的要插入太多行,所以我需要从csv文件中加载它?

我的电脑是Win7 32位,4GB内存,Core2Duo 1.86GHZ SQL Server 版本10.50.1617

首次查询

USE CustomerDB;

IF OBJECT_ID('Customer', 'U') IS NOT NULL
DROP TABLE Customer;

CREATE TABLE Customer
( 
CustomerID int PRIMARY KEY IDENTITY,
CustomerName nvarchar(16),
...about 130 more columns...
);

INSERT INTO Customer VALUES
('FirstCustomerName', ...),
...1500 more rows...
('LastCustomerName', ...)

经过10分钟以上仍未完成,我停止了查询,因为这显然是错误的。

第二次查询:

USE CustomerDB;

IF OBJECT_ID('Customer', 'U') IS NOT NULL
DROP TABLE Customer;

CREATE TABLE Customer
( 
CustomerID int PRIMARY KEY IDENTITY,
CustomerName nvarchar(16),
...about 130 more columns...
);

INSERT INTO Customer VALUES
('FirstCustomerName', ...);
INSERT INTO Customer VALUES
('SecondCustomerName', ...);
...1500 more ...
INSERT INTO Customer VALUES
('LastCustomerName', ...);

好的,低至 6.5秒,好多了但是对于1500个人来说仍然感觉很慢

第三次查询:

USE CustomerDB;

IF OBJECT_ID('Customer', 'U') IS NOT NULL
DROP TABLE Customer;

begin transaction Insert;

CREATE TABLE Customer
( 
CustomerID int PRIMARY KEY IDENTITY,
CustomerName nvarchar(16),
...about 130 more columns...
);

INSERT INTO Customer VALUES
('FirstCustomerName', ...);
INSERT INTO Customer VALUES
('SecondCustomerName', ...);
...1500 more ...
INSERT INTO Customer VALUES
('LastCustomerName', ...);

commit transaction Insert;

好的,直到 4.5-5秒,甚至更好,但我觉得还是有点慢

我不是DB / SQL Server大师,所以这是我自己来的,帮助将不胜感激!

编辑:既然我不是大师,那么在运行sql server的普通电脑上进行1500行插入时,4.5秒被认为是一段时间吗?

6 个答案:

答案 0 :(得分:3)

此插入很慢,因为您一次添加1行并且已完全记录。瓶颈不在于写入数据,它正在编写您在日志中所做的事情。

逐行插入并插入带有表锁的集合:

INSERT TABLENAME WITH(TABLOCK) (Column1,Column2,...)
 SELECT 'Column1Row1Value','Column2Row1Value'...
 UNION ALL
 SELECT 'Column1Row2value','Column2Row2Value'...
 UNION ALL
 SELECT 'Column1Row3value','Column2Row3Value'...

另外,请查看最小化记录事务的规则。

答案 1 :(得分:1)

您最有可能想要做一个这样的联合,而不是单独插入语句:

INSERT INTO Customer 
SELECT 'FirstCustomerName', ...
UNION
SELECT '2ndCustomerName', ...
UNION
SELECT '3rdCustomerName', ...
...1500 more rows...

这应该快得多。

答案 2 :(得分:1)

根据我的理解,您的列数会产生感觉。 但是你仍然检查以下几点可以帮助你。

  1. 如果行大小超过8 kb(页面大小)sql强制创建1个以上的页面来存储单行。
  2. 检查存在可变数据长度值的未使用的char数据类型(char列的总长度将存储在该空间中,这会增加大小)。
  3. 请避免使用Varchar(max),除非并且直到您期望在行中有如此庞大的数据。 varchar(max),nvarchar(max),如果我们不在行属性中启用文本,则图像存储在不同的页面中。
  4. 这是一个巨大的时间 - 基于您提到的行和数据大小。
  5. 如果需要任何帮助,请验证这些步骤并返回...

    就SQL而言,

    1500是一个非常小的数字:)

答案 3 :(得分:0)

桌上有一些索引吗?它们会降低insert语句的速度,因为在每个insert语句之后都会刷新索引表。

答案 4 :(得分:0)

运行插入时,请查看SQL Management Studio中的性能监视器。这可能会指出你正确的方向。

130列相当宽(取决于各个字段类型和大小)。这可能是与SQL Server相关的开销,必须在插入时管理和重新分配页面(page splitting)。性能监视器(或运行跟踪)将有助于确定是否是这种情况。

答案 5 :(得分:0)

您可以尝试使用其他插入格式。但是,我不确定它是否真的表现得更好。

INSERT INTO table_name
VALUES
 (100, 'Name 1', 'Value 1', 'Other 1'),
 (101, 'Name 2', 'Value 2', 'Other 2'),
 (102, 'Name 3', 'Value 3', 'Other 3'),
 (103, 'Name 4', 'Value 4', 'Other 4');

参考:http://www.electrictoolbox.com/mysql-insert-multiple-records/