SQL插入速度慢100万行

时间:2012-03-23 10:00:44

标签: performance tsql insert sql-server-2008-r2

WITH TOP 100000(100k)此查询在大约3秒内完成

WITH TOP 1000000(1mil)此查询在大约2分钟内完成

SELECT TOP 1000000
    db_id = IDENTITY(int, 1, 1), *
INTO dbo.tablename
FROM dbname.dbo.tablename

实际执行计划始终是:

clustered index scan 4% cost
top
top
compute scalar
insert (96% cost)
select into

该表有1.3 mil行,第一列有一个int主键

我能以某种方式加快速度吗?我正在使用SQL Server 2008 R2。

2 个答案:

答案 0 :(得分:2)

结果显示100,000条记录需要159毫秒,1,000,000条记录需要1,435毫秒。在Raid 1 OS上,Raid 1数据,Raid 1 Log,Raid 1 TempDb所有单独的驱动器。我们的开发环境。

结果显示,100,000条记录需要113毫秒,1,000,000条记录需要996毫秒。在我的笔记本电脑上使用单个SSD(三星840 250GB)。 SSD的摇滚!!!

结果显示100,000条记录需要188毫秒,1,000,000条记录需要1,880毫秒。在Raid 1 OS上,Raid 10 Data,Raid 10 Log,Raid 1 TempDb在生产负载下的所有单独驱动器。

答案 1 :(得分:1)

这是一个完整的脚本,显示100万不到10万次的十倍。你的情况可能略有不同,但这表明基本面不是问题。

结果显示100,000条记录需要146毫秒,1,000,000条记录需要1,315毫秒。

这些结果来自我的桌面。如果其他人可以运行该脚本并发布他们的结果,那将非常有用。

罗布

USE master;
GO
-- Drop database SourceDB
IF EXISTS (SELECT * FROM sys.databases WHERE name = 'SourceDB') ALTER DATABASE SourceDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
IF EXISTS (SELECT * FROM sys.databases WHERE name = 'SourceDB') DROP DATABASE  SourceDB;
GO
-- Create database SourceDB
CREATE DATABASE SourceDB; 
ALTER DATABASE SourceDB SET RECOVERY SIMPLE;
GO
USE SourceDB;
GO
-- Create table SourceDB.dbo.SourceTable
CREATE TABLE dbo.SourceTable (
    ColID int PRIMARY KEY
);
GO
-- Populate table SourceDB.dbo.SourceTable
DECLARE @i int = 0;
WHILE @i < 1300000
BEGIN
    SET @i += 1;
    INSERT INTO dbo.SourceTable (ColID) VALUES (@i);
END;
GO
-- Drop database Test1
IF EXISTS (SELECT * FROM sys.databases WHERE name = 'Test1') ALTER DATABASE Test1 SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
IF EXISTS (SELECT * FROM sys.databases WHERE name = 'Test1') DROP DATABASE  Test1;
GO
-- Create database Test1
CREATE DATABASE Test1;
ALTER DATABASE Test1 SET RECOVERY SIMPLE;
ALTER DATABASE Test1 MODIFY FILE (NAME = Test1, SIZE = 3000MB, MAXSIZE = 8TB);
ALTER DATABASE Test1 MODIFY FILE (NAME = Test1_log, SIZE = 3000MB, MAXSIZE = 2TB);
GO
USE Test1;
GO
IF EXISTS (SELECT * FROM sys.tables WHERE [OBJECT_ID] = OBJECT_ID('dbo.DestinationTable1')) DROP TABLE dbo.DestinationTable1;
IF EXISTS (SELECT * FROM sys.tables WHERE [OBJECT_ID] = OBJECT_ID('dbo.DestinationTable2')) DROP TABLE dbo.DestinationTable2;
GO
DECLARE @n  int       = 100000;
DECLARE @t1 datetime2 = SYSDATETIME();
SELECT TOP (@n) db_id = IDENTITY(int, 1, 1), *
INTO dbo.DestinationTable1
FROM SourceDB.dbo.SourceTable;
SELECT DATEDIFF(ms, @t1, SYSDATETIME()) AS ElapsedMs;
GO
DECLARE @n  int       = 1000000;
DECLARE @t1 datetime2 = SYSDATETIME();
SELECT TOP (@n) db_id = IDENTITY(int, 1, 1), *
INTO dbo.DestinationTable2
FROM SourceDB.dbo.SourceTable;
SELECT DATEDIFF(ms, @t1, SYSDATETIME()) AS ElapsedMs;
GO