WEB开发网
开发学院WEB开发ASP 使用Guid做主键和int做主键性能比较 阅读

使用Guid做主键和int做主键性能比较

 2010-01-06 10:42:57 来源:WEB开发网   
核心提示:在数据库的设计中我们常常用Guid或int来做主键,根据所学的知识一直感觉int做主键效率要高,使用Guid做主键和int做主键性能比较,但没有做仔细的测试无法说明道理,碰巧今天在数据库的优化过程中,以上观点代表个人观点,欢迎大家各抒己见,遇到此问题,于是做了一下测试
在数据库的设计中我们常常用Guid或int来做主键,根据所学的知识一直感觉int做主键效率要高,但没有做仔细的测试无法

说明道理。碰巧今天在数据库的优化过程中,遇到此问题,于是做了一下测试。



测试环境:

  台式电脑 Pentiun(R) 4 Cpu 3.06GHz
  Win XP PRofessional
  1.5G DDR RAM
  SQL Server 2005 个人版 



测试过程:
首先创建测试数据库Test
1.创建Test_Guid表,创建Test_Int表

代码
-------------------------------------------
--创建Test_Guid表
---------------------------------------------
USE Test
GO

IF OBJECT_ID('Test_Guid', 'U') IS NOT NULL
 DROP TABLE Test_Guid
GO

CREATE TABLE Test_Guid
(
  Guid varchar(50) not null,
  TestId int not null,
  TestText ntext not null,
  TestDateTime datetime default getdate(),
  CONSTRAINT PK_Guid PRIMARY KEY (Guid)
)
GO
---------------------------------------------
--创建Test_Int表
---------------------------------------------
USE Test
GO

IF OBJECT_ID('Test_Int', 'U') IS NOT NULL
 DROP TABLE Test_Int
GO

CREATE TABLE Test_Int
(
  Id int not null identity(1,1),
  TestId int not null,
  TestText ntext not null,
  TestDateTime datetime default getdate(),
  CONSTRAINT PK_Id PRIMARY KEY (Id)
)
GO


2.创建Test_Guid子表:Test_Guid_Detail和创建Test_Int子表:Test_Int_Detail,用来做连接查询

代码
--创建Test_Guid子表:Test_Guid_Detail
USE Test
GO

IF OBJECT_ID('Test_Guid_Detail', 'U') IS NOT NULL
 DROP TABLE Test_Guid_Detail
GO

CREATE TABLE Test_Guid_Detail
(
  Guid varchar(50) not null,--Guid是Test_Guid的外键
  TestId int not null,
  TestText ntext not null,
  TestDateTime datetime default getdate()--,
  --CONSTRAINT PK_Guid PRIMARY KEY (Guid)
)
GO
--创建Test_Int子表:Test_Int_Detail
USE Test
GO

IF OBJECT_ID('Test_Int_Detail', 'U') IS NOT NULL
 DROP TABLE Test_Int_Detail
GO

CREATE TABLE Test_Int_Detail
(
  Id int not null,--Id是Test_Int的外键
  TestId int not null,
  TestText ntext not null,
  TestDateTime datetime default getdate()--,
  --CONSTRAINT PK_Guid PRIMARY KEY (Guid)
)
GO


3.开始测试
测试1:测试Insert:向Test_Guid表中插入10万条记录

代码
---------------------------------------------
--测试Insert:向Test_Guid表中插入10万条记录
---------------------------------------------
declare @num int
declare @startTime datetime
set @num=0;
set @startTime=getdate()
while(@num<100000)
begin
  insert into Test_Guid
  values(newid(),@num,'测试guid',getdate())
  set @num=@num+1
end
select datediff(second,@startTime,getdate()) as 秒,datediff(ms,@startTime,getdate()) as 毫秒


测试2:测试Insert:向Test_Int表中插入10万条记录


代码
---------------------------------------------
--测试Insert:向Test_Int表中插入10万条记录
---------------------------------------------
declare @num int
declare @startTime datetime
set @num=0;
set @startTime=getdate()
while(@num<100000)
begin
  insert into Test_Int
  values(@num,'测试int',getdate())
  set @num=@num+1
end
select datediff(second,@startTime,getdate()) as 秒,datediff(ms,@startTime,getdate()) as 毫秒


测试3:测试Select:查找Test_Guid表中所有记录

代码
---------------------------------------------
--测试Select:查找Test_Guid表中所有记录
---------------------------------------------
declare @startTime datetime
set @startTime=getdate()
select * from Test_Guid
select datediff(second,@startTime,getdate()) as 秒,datediff(ms,@startTime,getdate()) as 毫秒


测试4:测试Select:查找Test_Int表中所有记录

代码
---------------------------------------------
--测试Select:查找Test_Int表中所有记录
---------------------------------------------
declare @startTime datetime
set @startTime=getdate()
select * from Test_Int
select datediff(second,@startTime,getdate()) as 秒,datediff(ms,@startTime,getdate()) as 毫秒


测试5:聚合查询:查找Test_Guid表中所有记录数

代码
---------------------------------------------
--聚合查询:查找Test_Guid表中所有记录
---------------------------------------------
declare @startTime datetime
set @startTime=getdate()
select count(*) from Test_Guid
select datediff(second,@startTime,getdate()) as 秒,datediff(ms,@startTime,getdate()) as 毫秒


测试6:聚合查询:查找Test_Int表中所有记录数

代码
---------------------------------------------
--聚合查询:查找Test_Int表中所有记录
---------------------------------------------
declare @startTime datetime
set @startTime=getdate()
select count(*) from Test_Int
select datediff(second,@startTime,getdate()) as 秒,datediff(ms,@startTime,getdate()) as 毫秒


测试7:测试带where条件的Select查询:查找Test_Int表中所有记录,都查找10000到50000之间的4万条记录

代码
----------------------------------------------------------------------------------------
--测试带where条件的Select查询:查找Test_Int表中所有记录,都查找10000到50000之间的4万条记录
----------------------------------------------------------------------------------------
declare @startTime datetime
set @startTime=getdate()
select * from Test_Guid where TestId between 10000 and 50000
select datediff(second,@startTime,getdate()) as 秒,datediff(ms,@startTime,getdate()) as 毫秒


测试8:测试带where条件的Select查询:查找Test_Int表中所有记录,都查找10000到50000之间的4万条记录

代码
----------------------------------------------------------------------------------------
--测试带where条件的Select查询:查找Test_Int表中所有记录,都查找10000到50000之间的4万条记录
----------------------------------------------------------------------------------------
declare @startTime datetime
set @startTime=getdate()
select * from Test_Int where TestId between 10000 and 50000
select datediff(second,@startTime,getdate()) as 秒,datediff(ms,@startTime,getdate()) as 毫秒


测试9:测试Test_Guid关联查询inner join

首先以Test_Guid中第一个Guid为外键,向Test_Guid_Detail中插入1万条记录

代码
---------------------------------------------
--向Test_Guid子表:Test_Guid_Detail中插入1万条记录
---------------------------------------------
declare @num int
declare @topGuid nvarchar(50)
set @num=0;
select top 1 @topGuid=Guid from Test_Guid
while(@num<10000)
begin
  insert into Test_Guid_Detail
  values(@topGuid,@num,'测试guid的子表',getdate())
  set @num=@num+1
end



然后开始测试:

代码
---------------------------------------------
--测试连接查询:查找Test_Guid表和Test_Guid_Detail所有关联的记录
---------------------------------------------
declare @startTime datetime
set @startTime=getdate()
select T.* from Test_Guid T
inner join Test_Guid_Detail T1 on T.Guid=T1.Guid
select datediff(second,@startTime,getdate()) as 秒,datediff(ms,@startTime,getdate()) as 毫秒
测试10:测试Test_Int关联查询inner join

首先以Test_Int中第一个id为外键,向Test_Int_Detail中插入1万条记录

代码
---------------------------------------------
--向Test_Int子表:Test_Int中插入1万条记录
---------------------------------------------
declare @num int
declare @topInt int
set @num=0;
select top 1 @topInt=Id from Test_Int
while(@num<10000)
begin
  insert into Test_Int_Detail
  values(@topInt,@num,'测试int的子表',getdate())
  set @num=@num+1
end


然后开始测试:

代码
---------------------------------------------
--测试连接查询:查找Test_Int表和Test_Int_Detail所有关联的记录
---------------------------------------------
declare @startTime datetime
set @startTime=getdate()
select T.* from Test_Int T
inner join Test_Int_Detail T1 on T.id=T1.id
select datediff(second,@startTime,getdate()) as 秒,datediff(ms,@startTime,getdate()) as 毫秒
测试11:测试Update:更新Test_Guid表中所有记录

代码
---------------------------------------------
--测试Update:查找Test_Guid表中所有记录
---------------------------------------------
declare @startTime datetime
set @startTime=getdate()
update Test_Guid set TestText='测试guid更新'
select datediff(second,@startTime,getdate()) as 秒,datediff(ms,@startTime,getdate()) as 毫秒


测试12:测试Update:更新Test_Int表中所有记录

代码
---------------------------------------------
--测试Update:查找Test_Int表中所有记录
---------------------------------------------
declare @startTime datetime
set @startTime=getdate()
update Test_Int set TestText='测试int更新'
select datediff(second,@startTime,getdate()) as 秒,datediff(ms,@startTime,getdate()) as 毫秒


测试13:测试Delete:删除Test_Guid表中所有记录

代码
---------------------------------------------
--测试Delete:查找Test_Guid表中所有记录
---------------------------------------------
declare @startTime datetime
set @startTime=getdate()
delete from Test_Guid
select datediff(second,@startTime,getdate()) as 秒,datediff(ms,@startTime,getdate()) as 毫秒
delete from Test_Guid_Detail


测试14:测试Delete:删除Test_Int表中所有记录

代码
---------------------------------------------
--测试Delete:查找Test_Int表中所有记录
---------------------------------------------
declare @startTime datetime
set @startTime=getdate()
delete from Test_Int
select datediff(second,@startTime,getdate()) as 秒,datediff(ms,@startTime,getdate()) as 毫秒
delete from Test_int_Detail


综上所述,使用int做主键比用guid做主键各中情况下效率均有提高,特别是在有连接查询和删除记录效率提升明显。

而且本人今日在guid做主键的数据查询中因为嵌套几个子查询结果屡屡出现查询超时。因此本人赞同用int做主键,不赞同guid做主键。
以上观点代表个人观点,欢迎大家各抒己见,说明guid和int各自做主键的优劣所在。

附上测试脚本供大家测试:http://files.cnblogs.com/jackhuclan/guid.rar

Tags:使用 Guid 做主

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接