2012-03-23 119 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所有獨立驅動器。