今天上班,发现一个同事用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和Int类型主键效率的比较
计算机等考三级数据库辅导:使用GUID作为数据表主键的好处.docx
数据库中使用自增量字段与Guid字段主键的性能对比
GUID生成程序,生成后可用来做数据库的主键,非常好用!!!
DELPHI 开发分层,常用TDataSetProvider 联ADO TADODataSet。在开发主从表时用TGUID做主键时。出现了问题。 问题就在ADODB单元的GetFilterStr函数。 GetFilterStr.txt 内是我修改过的函数
MySQL中国省市区地名表 Guid主键
GUID 的优点带来的便利远超出其缺点带来的影响,随着诸如 WebService 等系统互联与整合技术的不断发展,其唯一标识的特性使得其应用越来越广,在您的应用程序中也应考虑使用它了。
用hibernate方式配置生成mysql guid数据,32位的,在eclipse下直接导入,运行即可
SQLServer分页存储过程通常有多个版本,但是效率上有高有低,经过测试排名为: 版本1:select max 版本2:row_number 版本3:not in 版本4:临时表 版本5:中间变量 ...如果主键为guid,请使用版本2
GUID生成器 GUID生成小程序 快速生成GUID,自动复制到剪贴板。
生成GUID程序,C#源代码,System.Guid.NewGuid().ToString()全球唯一标识符 (GUID) 是一个字母数字标识符,用于指示产品的唯一性安装。在许多流行软件应用程序(例如 Web 浏览器和媒体播放器)中,都使用 GUID。 GUID...
模仿VS自带的GUID生成器,可生产GUID编码,点击即可复制到粘贴板
LabVIEW通过调用.net实现全球唯一码GUID的生成。 只有一个VI,简单快捷。
轻松修改文件guid的小工具。全局唯一标识替换工具,作者Yonsm.net
GUID生成工具源码 guid生成工具,有源码的。 .NET C# GUID自动生成
sql server2000 下创建guid的主键语法,适用于从oracle转移到sql上使用
一个简单的实现guid算法的程序代码!这主要是应用c#语言编写的后台代码!
华擎主板用编程器刷BIOS后,会造成1394GUID丢失,开机启动后必须按F1才能继续下一步(进BIOS、选择启动菜单、进操作系统)。用此工具可重新写入1394GUID,免去开机后按F1的烦恼。
Guid生成器,方便快捷, 下面的字水了: 全局唯一标识符(GUID,Globally Unique Identifier)是一种由算法生成的二进制长度为128位的数字标识符。GUID主要用于在拥有多个节点、多台计算机的网络或系统中。在理想...
CString CTestGetUUIDDlg::newGUID() { CString buf; GUID guid; if (S_OK == ::... , guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5] , guid.Data4[6], guid.Data4[7]); } return buf; }