千萬數據的連續ID表,快速讀取其中指定的某1000條數據?

作者: 邀月  來源: 博客園  發布時間: 2010-08-29 19:56  閱讀: 2386 次  推薦: 0   原文鏈接   [收藏]  
 
摘要:一張上千萬數據的表,結構很簡單:ID是自增的,你怎么快速讀取其中指定的某1000條數據,比如100萬到100萬零1000?怎么做呢?看下文。
[1] 千萬數據的連續ID表,快速讀取其中指定的某1000條數據?
[2] 千萬數據的連續ID表,快速讀取其中指定的某1000條數據?

  有這樣一個需求:一張上千萬數據的表,結構很簡單:ID是自增的,你怎么快速讀取其中指定的某1000條數據,比如100萬到100萬零1000?這個需求其實很簡單,因為是自增型ID,可能分兩種狀況:有聚集索引或Heap,如果是后者,我想用ID和新增時間組建非聚集索引。效果應該相差不大。于是動手,過程如下:

  一、準備測試數據

  基本測試環境:
邀月工作室

  插入1000萬測試數據:

 

/***************創建千萬級測試數據庫***********
****************downmoon 3w@live.cn **************
*/

Create database HugeData_10Millons
go
use HugeData_10Millons
go

/***************創建測試表*********************
****************downmoo 3w@live.cn **************
*/

IF NOT OBJECT_ID('[bigTable]') IS NULL
DROP TABLE [bigTable]
GO
Create table bigTable
(PID
int identity(1,1) primary key not null
,PName nvarchar(100) null
,AddTime dateTime null
,PGuid Nvarchar(40)
)

go

truncate table [bigTable]

/***************創建第一個25萬測試數據*********************
****************downmoo 3w@live.cn **************
*/

declare @d datetime
set @d=getdate()

declare @i int
set @i=1
while @i<=250000
begin
insert into [bigTable]
select cast(datepart(ms,getdate()) as nvarchar(3))+Replicate('A',datepart(ss,getdate()))
,
getdate()
,
NewID()
set @i=@i+1
end

select [語句執行花費時間(毫秒)]=datediff(ms,@d,getdate())

/*
語句執行花費時間(毫秒)
94750

*/

/***************創建第二個25萬測試數據*********************
****************downmoo 3w@live.cn **************
*/

declare @d datetime
set @d=getdate()

declare @i int
set @i=1
while @i<=250000
begin
insert into [bigTable]
select cast(datepart(ms,getdate()) as nvarchar(3))+Replicate(Substring(cast(NEWID() as nvarchar(40)),1,6),3)
,
getdate()
,
NewID()
set @i=@i+1
end

select [語句執行花費時間(毫秒)]=datediff(ms,@d,getdate())

/*
語句執行花費時間(毫秒)
115640

*/

/***************創建900萬測試數據*********************
****************downmoo 3w@live.cn **************
*/

declare @d datetime
set @d=getdate()

declare @i int
set @i=1
while @i<=9000000
begin
insert into [bigTable]
select replicate('X',ROUND((RAND()* 60),0) )+cast(datepart(ms,getdate()) as nvarchar(3))
,
getdate()
,
NewID()
set @i=@i+1
end

select [語句執行花費時間(毫秒)]=datediff(ms,@d,getdate())
/*
語句執行花費時間(毫秒)
3813686

*/

/***************創建最后50萬測試數據*********************
****************downmoo 3w@live.cn **************
*/

declare @d datetime
set @d=getdate()

declare @i int
set @i=1
while @i<=500000
begin
insert into [bigTable]
select replicate('X',ROUND((RAND()* 60),0) )+cast(NewID() as nvarchar(40))
,
getdate()
,
NewID()
set @i=@i+1
end

select [語句執行花費時間(毫秒)]=datediff(ms,@d,getdate())
/*
語句執行花費時間(毫秒)
207436

*/

/*
檢查數量
select count(1) from dbo.bigTable
----------10000000
清除日志
DUMP TRANSACTION HugeData_10Millons WITH NO_LOG
BACKUP LOG HugeData_10Millons WITH NO_LOG
DBCC SHRINKDATABASE(HugeData_10Millons)


*/
  完成后,數據文件大小如下:

 

邀月工作室

  二、創建一個存儲過程用于測試

 

/***************查中間某段1000條順序數據*********************
****************downmoo 3w@live.cn **************
*/
Create procedure GetTop1000RecordsByRange
(
@begin int
,@end int
)
as
select top 1000 * from [bigTable]
where PID between @begin and @end
go
  邀月說明:其實,加不加top對查詢并沒有影響。后面的測試證實了這一點。因為將top 1000 去掉后,清除過程計劃緩存,仍然得出相同的計劃結果。

 

  測試語句:

 
declare @d datetime
set @d=getdate()

exec GetTop100RecordsByRange 1000000,10001000

select [語句執行花費時間(毫秒)]=datediff(ms,@d,getdate())

  此時,由于SQL Server默認為主鍵PID創建了聚集索引,查詢速度比較理想,平均為0-16毫秒之間,更接近于0

  查詢計劃也如我所料:
邀月工作室   而如果以Pguid作為聚集索引鍵,查詢計劃如下:
邀月工作室

  如果以AddTime作為聚集索引鍵,查詢計劃:
邀月工作室

[第1頁][第2頁]
0
0
 
標簽:SQL Server
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()