原文:使用NEWSEQUENTIALID解决GUID聚集索引问题

UNIQUEIDENTIFIER做主键(Primary Key)是一件很方便的事情,在数据合并等操作中有不可替代的优势

但是由于普通的GUID的分散性使得如果主键加上聚集索引(Clustered Index)会导致在插入记录时效率大大降低



SQL SERVER 2005中新增了一个NEWSEQUENTIALID的函数,MSDN的解释是:

在指定计算机上创建大于先前通过该函数生成的任何 GUID 的 GUID。

NEWSEQUENTIALID() 不能在查询中引用。

注:即只能做为数据库列的DEFAULT VALUE,不能执行类似SELECT NEWSEQUENTIALID()的语句

只有当计算机没有网卡时,NEWSEQUENTIALID() 生成的 GUID 才在该特定计算机中是唯一的。

注:这句话是错误的,应该是只有只有当计算机有网卡时,生成的GUID才是全球唯一

您可以使用 NEWSEQUENTIALID() 生成 GUID 以减少叶级别索引上的页争用。



但是使用NEWSEQUENTIALID却不是那么一帆风顺

1. 如何获得生成的GUID

如果生成的GUID所在字段做为外键要被其他表使用,我们就需要得到这个生成的值

通常,PK是一个IDENTITY字段,我们可以在INSERT之后执行 SELECT SCOPE_IDENTITY()来获得新生成的ID

但是由于NEWSEQUENTIALID()不是一个INDETITY类型,这个办法是做不到了,而他本身又只能在默认值中使用,不可以事先SELECT好再插入,那么我们如何得到呢?有以下两种方法:

--1. 定义临时表变量 

DECLARE @outputTable TABLE(ID uniqueidentifier)

INSERT INTO TABLE1(col1, col2)

OUTPUT INSERTED.ID INTO @outputTable

VALUES('value1', 'value2')

SELECT ID FROM @outputTable



--2. 标记ID字段为ROWGUID(一个表只能有一个ROWGUID)

INSERT INTO TABLE1(col1, col2)

VALUES('value1', 'value2')

--在这里,ROWGUIDCOL其实相当于一个别名

SELECT ROWGUIDCOL FROM TABLE1

2. 如何设定DEFAULT VALUE为NEWSEQUENTIALID()

通过UI的方式设定默认值时,由于SQL SERVER 2005的BUG(即使是SP2也没有解决),导致我们设置了默认值为NEWSEQUENTIALID()保存时会出现以下错误:

Warning were encountered during the pre-save validation process, and might result in a failure during save. Do you want to continue attempting to save?

'Table1' Table

-Error validating the default for column 'Id'

有两种方式可以解决:要么直接点Yes,要么通过CREATE TABLE语句来建表。



通过客户端的方式,也可以通过调用windows api产生sequential的guid,虽说可以省去上面提到的两种麻烦,但是经过我测试,效果不是那么好。

我建立了一个表有ID和TIMESTAMP两个字段,用NEWSEQUENTIALID()和客户端两种方法生成记录,并按ID和TIMESTAMP两种方式进行排序。

NEWSEQUENTIALID()版本的结果永远一样。而客户端生成就有一些问题,如果连续运行程序,表现良好,如果间隔一段时间后继续运行,新生成的记录就不一定大于之前生成的记录,而每次间隔之间连续运行的部分,仍然表现良好。

客户端生成sequential guid代码如下

 1    public static class SequentialGuid

 2    {

 3        [DllImport("rpcrt4.dll", SetLastError = true)]

 4        static extern int UuidCreateSequential(out Guid guid);

 5

 6        public static Guid NewGuid()

 7        {

;

 9

            Guid guid;

            int result = UuidCreateSequential(out guid);

            if (result != RPC_S_OK)

            {

                throw new ApplicationException("Create sequential guid failed: " + result);

            }



            return guid;

        }

    }

使用NEWSEQUENTIALID解决GUID聚集索引问题的更多相关文章

  1. [O]SQL SERVER下有序GUID和无序GUID作为主键&聚集索引的性能表现

     背景 前段时间学习<Microsoft SQL Server 2008技术内幕:T-SQL查询>时,看到里面关于无序GUID作为主键与聚集索引的建议,无序GUID作为主键以及作为聚集索引 ...

  2. SQL SERVER下有序GUID和无序GUID作为主键&聚集索引的性能表现

     背景 前段时间学习<Microsoft SQL Server 2008技术内幕:T-SQL查询>时,看到里面关于无序GUID作为主键与聚集索引的建议,无序GUID作为主键以及作为聚集索引 ...

  3. 聚簇索引(聚集索引) 不可作用于GUID类型字段

    聚簇索引(又名聚集索引) 不可作用于GUID类型字段,即:数据库中不要把GUID类型作为主键或设置为聚集索引. 聚集索引:索引的物理存储顺序与数据表中行数据物理存储顺序一致(索引存储物理有序). 非聚 ...

  4. SQL SERVER 聚集索引 非聚集索引 区别

    转自http://blog.csdn.net/single_wolf_wolf/article/details/52915862 一.理解索引的结构 索引在数据库中的作用类似于目录在书籍中的作用,用来 ...

  5. SQLSERVER聚集索引与非聚集索引的再次研究(上)

    SQLSERVER聚集索引与非聚集索引的再次研究(上) 上篇主要说聚集索引 下篇的地址:SQLSERVER聚集索引与非聚集索引的再次研究(下) 由于本人还是SQLSERVER菜鸟一枚,加上一些实验的逻 ...

  6. SQLSERVER聚集索引与非聚集索引的再次研究(下)

    SQLSERVER聚集索引与非聚集索引的再次研究(下) 上篇主要说了聚集索引和简单介绍了一下非聚集索引,相信大家一定对聚集索引和非聚集索引开始有一点了解了. 这篇文章只是作为参考,里面的观点不一定正确 ...

  7. SQL Server 2014新特性探秘(3)-可更新列存储聚集索引

    简介      列存储索引其实在在SQL Server 2012中就已经存在,但SQL Server 2012中只允许建立非聚集列索引,这意味着列索引是在原有的行存储索引之上的引用了底层的数据,因此会 ...

  8. [翻译] 聚集索引表 VS 堆表

    前言: 本文对这篇博客Clustered Tables vs Heap Tables 的翻译, 如有翻译不对或不好的地方,敬请指出,大家一起学习进步. 问题描述 创建一个新表时,一个非常重要的设计原则 ...

  9. Sql Server之旅——第三站 解惑那些背了多年聚集索引的人

    说到聚集索引,我想每个码农都明白,但是也有很多像我这样的猥程序员,只能用死记硬背来解决这个问题,什么表中只能建一个聚集索引, 然后又扯到了目录查找来帮助读者记忆....问题就在这里,我们不是学文科,, ...

随机推荐

  1. js如何实现动态的在表格中添加和删除行?(两种方法)

    js如何实现动态的在表格中添加和删除行?(两种方法) 一.总结 1.table元素有属性和一些方法(js使用) 方法一:添加可通过在table的innerHTML属性中添加tr和td来实现 tab.i ...

  2. php标准库spl栈SplStack如何使用?

    php标准库spl栈SplStack如何使用? 一.总结 php标准库spl栈SplStack介绍.(SplStack类)(各种方法都支持) 1.SplStack类:$stack = new SplS ...

  3. C语言实现使用动态数组来构造栈结构

    我在面前一篇博客<C语言实现使用静态数组来构造栈结构>中使用了静态数组来模拟栈的操作.静态数组的大小是在代码中写死的.是存储在用户栈上面的,使用起来不灵活.在这篇博客中我会使用动态数组来构 ...

  4. Warning: file_put_contents(常用单词1.txt): failed to open stream: Invalid argument in

    Warning: file_put_contents(常用单词1.txt): failed to open stream: Invalid argument in 一.总结 1.上述问题是因为Win ...

  5. cocos2d-x AnchorPoint锚点

    锚点是定位和变换操作的一个重点.锚点我们能够看成用一根图钉将一张纸或者相片钉在墙上的那个点. 节点的位置是由我们设置的position和anchor point一起决定的. 值得一提的是,anchor ...

  6. 二维高斯滤波器(gauss filter)的实现

    我们以一个二维矩阵表示二元高斯滤波器,显然此二维矩阵的具体形式仅于其形状(shape)有关: def gauss_filter(kernel_shape): 为实现二维高斯滤波器,需要首先定义二元高斯 ...

  7. python 爬取36kr 7x24h快讯

    url为https://36kr.com/newsflashes,抓包后发现第一次的新闻内容就是包含在<script>var props={}></script>标签中, ...

  8. Atititjs javascript异常处理机制java异常转换.js exception process

    Atititjs javascript异常处理机制java异常的转换.js exception process 1. javascript异常处理机制 Throw str Not throw erro ...

  9. C#依赖注入控制反转IOC实现详解

    原文:C#依赖注入控制反转IOC实现详解 IOC的基本概念是:不创建对象,但是描述创建它们的方式.在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务.容器负责将这些联系在一起. ...

  10. scipy 图像处理(scipy.misc、scipy.ndimage)、matplotlib 图像处理

    from scipy.misc import imread / imsave / imshow imresize / imrotate / imfilter 1. scipy.misc 下的图像处理 ...