guid跟sequence做主键的比较

系统 1857 0

今天上班,发现一个同事用oracle的sys_guid()来做从一个表中随机获取6条记录:
select * from (select * from tablename order by sys_guid()) where rownum < 7;
看得出来是先创建guid,然后将表记录按照这个guid排序,再从中取头6条。
数据库主键用guid我倒是见过,这样用作取随机数倒是头一次碰上。

立刻又想到oracle用guid作主键,跟sequnce比较哪个更好。google中还是找到了一篇文章说的比较好:

http://sgsoft.itpub.net/post/28147/270097

 

最近又有朋友争论起 SYS_GUID sequence 谁做主键更合适的问题。下面我以一个案例说明一下,两者在实际应用中的情况。以下内容纯属个人研究,观点亦仅限于本案例

记得A项目组是一个物流管理系统,后台采用了Oracle数据库。在系统中的核心表托运单表中,关于主键采用何种数据类型,是 sequence 还是用 GUID 大家起了争论。

从网络搜索得到的结论看,一般的意见总结为:
1.
SYS_GUID()比sequence复杂;
2.SYS_GUID做主键,则表、索引存储开销多;
3.SYS_GUID索引查询比sequence慢;
下面对SYS_GUID和Sequence做主键的情况进行以下对比.
edl@PISC> select count(*) from all_objects;

COUNT(*)

----------

50231

已用时间 : 00: 00: 02.52

创建下列对象:

create table tsg as select RAWTOHEX(sys_guid()) sgid,a.* from all_objects a;

create SEQUENCE seq_tsg;

create table tsg2 as select seq_tsg.nextval,a.* from all_objects a;

空间比较

现在这两个表:tsg和tsg2拥有的行数相同,但大小不同:

行数

Number Extents

Size in bytes

索引大小

TSG(SYS_GUID主键)

50231

23

8388608

3145728

TSG2(Sequence主键)

50231

21

6291456

917504

换言之 相同条件下 使用 SYS_GUID 做主键比用 Sequence 做主键 ,表 多消耗了空间 2097152 byte, 索引多消耗 2228224 byte, 平均每行多消耗 86.1 byte.

考虑到生产环境下 , 每天 5 万条记录 , 则一年 365*50000=18250000 条记录 , 则理论上需要多耗费空间约合 1.43GB 存储空间 . 这些空间对磁盘消耗而言可以忽略不计,对内存仍然是有一定影响的,但就当前的服务器能力而言,影响有限,如果对表进行合理分区后,这种影响可以降低至极低。

执行计划比较

比较唯一查询时的执行计划 :

TSG 执行 :

select owner

from tsg

where sgid = 'F36C09B7A7A84297995352D2409EB40E'

TSG2 执行 :

select owner

from tsg2

where sgid = 99

执行计划比较如下 :

统计信息对比 :

从以上统计信息看 , 执行计划相同。
可以预料到的是 , 由于使用 SYS_GUID 做主键 , 比较的是字符串 , 故耗费 CPU 要高些 , 因此 ,logical reads 要高些 , 至于 Physical Readers 居然低一些 , 就不知道原因了(实际上二者基本都没有产生大量的物理读) , 估计是我的测试环境 Db Cache 太小的缘故 .

对于响应时间 , 这应该是计算机环境产生的影响 , 不能说明问题,这两条语句响应都很快 , 小于 0.02 .

小结

从实践来看 , 使用 SYS_GUID() 做主键的优点多于负面影响。特别是在多个数据库数据集成时 ,GUID 的优点显而易见 . A项目最终没有采用客户定义的“货单唯一序号”作为主键,也是出于关系数据库设计的法则约定:“主键不要代表任何意义”。

综上所述, SYS_GUID 做主键:

SYS_GUID sequence 复杂 === è 有限范围的正确 :由于 SYS_GUID RAW 类型的,做主键是,需要使用 RAWTOHEX 或者 HEXTORAW 类的函数转换,若直接使用,则需要建立函数索引等。但这种复杂性往往在前端业务系统中体现不出,主键常常作为隐含的唯一 ID 去标识对象,而不显示出来(或者不手工操作它,因为它无意义)。

SYS_GUID 做主键存储开销大 = è 不需要评估系统规模:如今存储非常便宜,内存也足够大,如果 2 千万条记录增加不到1.5G内存的话,当前普通的服务器已经可以承受,如果进行合理分区,则影响可以降低到极低。当然,如果您的服务器资源很紧张,那恐怕得放弃使用SYS_GUID

SYS_GUID 做主键查询比 sequence è 不正确:实践证明,二者是一样的。

 

guid跟sequence做主键的比较


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论