主键设定与数据库查询

在数据库表设计时,许多人为采用INT类型还是GUID(uniqueidentifyer)作为主键争论不休,有认为int型字段好的,有认为GUID好的,很多时候的焦点集中在效率上。

为了弄清事实真相,我想还是要以实验来进行测试为准。以下就是为了测试插入效率而写的一段脚本。测试环境是:Xeon 1.6/2G内存 win2003/sqlserver2005 企业版。

测试脚本:

--测试无主键/Identity/Uniqueidentifier/varchar类型主键插入表时的效率

代码
    
      
set nocount on
declare @now datetime , @i int
set @i = 1
set @now = getdate ()
Create table test1(nopkey int ,col uniqueidentifier )
while @i < 10000000
Begin
insert into test1 values ( 1 , newid ())
set @i = @i + 1
end
Print ' 新表无主键插入100万条数据所耗时间: ' + convert ( varchar ( 200 ), datediff (ms, @now , Getdate ())) + ' 毫秒 '

set @i = 1
set @now = getdate ()
while @i < 10000
Begin
insert into test1 values ( 1 , newid ())
set @i = @i + 1
end
Print ' 100万行中再插入10000条数据时间: ' + convert ( varchar ( 200 ), datediff (ms, @now , Getdate ())) + ' 毫秒 '

GO
Create table Test2(pkey int identity ( 1 , 1 ) primary key , col uniqueidentifier default ( newid ()))
declare @now datetime , @i int
set @i = 1
set @now = getdate ()
while @i < 1000000
Begin
insert into test2(col) values ( newid ())
set @i = @i + 1
end
Print ' 新表以int为主键插入100万条数据所耗时间: ' + convert ( varchar ( 200 ), datediff (ms, @now , Getdate ())) + ' 毫秒 '

set @i = 1
set @now = getdate ()
while @i < 10000
Begin
insert into test2(col) values ( newid ())
set @i = @i + 1
end
Print ' 100万行中再插入10000条数据所耗时间: ' + convert ( varchar ( 200 ), datediff (ms, @now , Getdate ())) + ' 毫秒 '
GO

Create table test3(Pkey uniqueidentifier Primary key , col int )
declare @now datetime , @i int
set @i = 1
set @now = getdate ()
while @i < 1000000
Begin
insert into test3 values ( newid (), 3 )
set @i = @i + 1
end

Print ' 新表以uniqueidentifier主键插入100万条数据所耗时间: ' + convert ( varchar ( 200 ), datediff (ms, @now , Getdate ())) + ' 毫秒 '

set @i = 1
set @now = getdate ()
while @i < 10000
Begin
insert into test3 values ( newid (), 3 )
set @i = @i + 1
end
Print ' 100万行中再插入10000条数据所耗时间: ' + convert ( varchar ( 200 ), datediff (ms, @now , Getdate ())) + ' 毫秒 '

GO

Create table test4(Pkey varchar ( 36 ) Primary key , col int )
declare @now datetime , @i int
set @i = 1
set @now = getdate ()
while @i < 1000000
Begin
insert into test4 values ( convert ( varchar ( 36 ), newid ()), 3 )
set @i = @i + 1
end
Print ' 新表以varchar(36)类型为主键插入100万条数据:所耗时间: ' + convert ( varchar ( 200 ), datediff (ms, @now , Getdate ())) + ' 毫秒 '
set @i = 1
set @now = getdate ()
while @i < 10000
Begin
insert into test4 values ( convert ( varchar ( 36 ), newid ()), 3 )
set @i = @i + 1
end
Print ' 100万行中再插入10000条数据所耗时间: ' + convert ( varchar ( 200 ), datediff (ms, @now , Getdate ())) + ' 毫秒 '

GO
drop table test1
drop table test2
drop table test3
drop table test4

 

 

运行测试结果如下:

新表无主键插入100万条数据所耗时间:1212856毫秒
100万行中再插入10000条数据时间:19360毫秒
新表以int为主键插入100万条数据所耗时间:111623毫秒
100万行中再插入10000条数据所耗时间:1110毫秒
新表以uniqueidentifier主键插入100万条数据所耗时间:118753毫秒
100万行中再插入10000条数据所耗时间:1153毫秒
新表以varchar(36)类型为主键插入100万条数据所耗时间:132830毫秒
100万行中再插入10000条数据所耗时间:1263毫秒 经过多次测试,均为相应结果,可见在插入表时,对于无主键和有主键的表来说,无主键的表其插入效率最低,其次是Varchar,uniqueidentifier和int 从测试结果看,int类型和uniqueidentifier类型的插入时间相差无几,在2005下如果插入一两条记录的情况下应该是没有什么影响,而采用uniq这种类型的字段,在编程取ID和转移数据方面有着很大的优势,至于它占用空间比int类型要多一些,这对于本身就是超大的数据库而言应该不是太大问题。

 

 

 

另外一人提供的数据:

统计:

 新表无主键插入100万条数据所耗时间:2397270毫秒

100万行中再插入10000条数据时间:2420毫秒

查询数据所耗时间:79980毫秒

统计数据所耗时间:690毫秒

 

新表以int为主键插入100万条数据所耗时间:195570毫秒

 100万行中再插入10000条数据所耗时间:1760毫秒

查询数据所耗时间:7866毫秒

统计数据所耗时间:110毫秒

 

 新表以uniqueidentifier主键插入100万条数据所耗时间:207506毫秒

100万行中再插入10000条数据所耗时间:2410毫秒

查询数据所耗时间:7696毫秒

统计数据所耗时间:76毫秒

 

新表以varchar(36)类型为主键插入100万条数据:所耗时间:227616毫秒

100万行中再插入10000条数据所耗时间:2250毫秒

查询数据所耗时间:9416毫秒

统计数据所耗时间:93毫秒

 

 

 

以上是别人提供的数据,经过我的测试(我的机子为2.8GHZ,内存为1G)数据如下:

以GUID作主键时:

以uniqueidentifier主键插入100万条数据所耗时间:800123毫秒

100万行中再插入10000条数据所耗时间:7970毫秒

 

以Int型作主键时:

所耗时间:

新表以int为主键插入100万条数据所耗时间:1067796毫秒
100万行中再插入10000条数据9360毫秒

 

查询时:

 

   
     
declare @startTime datetime
set @startTime = getdate ()
select * from test3
select datediff (second, @startTime , getdate ())as秒, datediff (ms, @startTime , getdate ())as毫秒

 

 

 

查询所有时(101000000条):

用GUID 作主键时:

  秒           毫秒

130       130876

 

用INT 作主键时:

   秒         毫秒

 141     140626

 

 

当查询一条时,测试不出来,结果均为0毫秒。

你可能感兴趣的:(数据库)