|
有这样一个需求:一张上千万数据的表,结构很简单:ID是自增的,你怎么快速读取其中指定的某1000条数据,比如100万到100万零1000?这个需求其实很简单,因为是自增型ID,可能分两种状况:有聚集索引或Heap,如果是后者,我想用ID和新增时间组建非聚集索引。效果应该相差不大。于是动手,过程如下:
一、准备测试数据
基本测试环境:
插入1000万测试数据: it知识库:千万数据的连续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)
*/
三、修改聚集索引,以检查查询速度/*删除系统自动创建的聚集索引
*/
ALTER TABLE [dbo].[bigTable] DROP CONSTRAINT [PK__bigTable__7C8480AE]
go
/*创建一个非聚集索引
在PID和addtime字段
*/
CREATE NONCLUSTERED INDEX bigTable_NoClusIdx
ON [bigTable]([AddTime] ASC,[PID] ASC);
go
DROP Index [bigTable_NoClusIdx] on dbo.[bigTable]
/*创建一个非聚集索引
在PID字段
*/
Create NONCLUSTERED INDEX bigTable_NoclusIdx
ON [bigTable](PID);
go
DROP Index [bigTable_NoClusIdx] on dbo.[bigTable]
/*创建一个非聚集索引
在AddTime字段
*/
CREATE NONCLUSTERED INDEX bigTable_NoclusIdx
ON [bigTable](AddTime);
go
DROP Index [bigTable_NoClusIdx] on dbo.[bigTable]
/*创建一个非聚集索引
在GUID字段
*/
CREATE NONCLUSTERED INDEX bigTable_NoclusIdx
ON [bigTable](PGuid);
go
DROP Index [bigTable_NoClusIdx] on dbo.[bigTable]
/*创建一个聚集索引
在GUID字段
*/
CREATE CLUSTERED INDEX bigTable_ClusIdx
ON [bigTable](PGuid);
go
DROP Index [bigTable_ClusIdx] on dbo.[bigTable]
/*创建一个聚集索引
在addTime字段
*/
CREATE CLUSTERED INDEX bigTable_ClusIdx
ON [bigTable](AddTime);
go
DROP Index [bigTable_ClusIdx] on dbo.[bigTable]
/*创建一个聚集索引
在PID字段
*/
CREATE CLUSTERED INDEX bigTable_ClusIdx
ON [bigTable](PID);
go