2012-03-23 89 views
3

WITH TOP 100000(100K)缓慢这个查询是在大约3秒SQL插入1个百万行

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密耳的行,并且对第一列

一个int主键10

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

+0

您确定SQL Server不只是忙于扩展.mdf或.ldf吗? – Filburt 2012-03-23 10:15:21

+0

嗯,那么为什么(例如)从.bak文件中恢复GB级备份的速度要快于此时的全部磁盘空间分配? – cdbeelala89 2012-03-23 10:22:30

+1

因为如果您将自动展开设置为百分比而不是固定数量,它将不断地忙于分配更多空间。在恢复(通过现有的)数据库时,所需的大小已知,可以一次分配。 – Filburt 2012-03-23 10:25:50

回答

1

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

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

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

罗布

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 
2

结果表明,10万条记录需要159毫秒,1,000,000记录时,需要1435毫秒。在Raid 1操作系统上,Raid 1 Data,Raid 1 Log,Raid 1 TempDb所有独立驱动器。我们的Dev环境。

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

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