使用NEWSEQUENTIALID解决GUID聚集索引问题
原文:使用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 TABLE12. 如何设定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代码如下
public static class SequentialGuid2

{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聚集索引问题的更多相关文章
- [O]SQL SERVER下有序GUID和无序GUID作为主键&聚集索引的性能表现
背景 前段时间学习<Microsoft SQL Server 2008技术内幕:T-SQL查询>时,看到里面关于无序GUID作为主键与聚集索引的建议,无序GUID作为主键以及作为聚集索引 ...
- SQL SERVER下有序GUID和无序GUID作为主键&聚集索引的性能表现
背景 前段时间学习<Microsoft SQL Server 2008技术内幕:T-SQL查询>时,看到里面关于无序GUID作为主键与聚集索引的建议,无序GUID作为主键以及作为聚集索引 ...
- 聚簇索引(聚集索引) 不可作用于GUID类型字段
聚簇索引(又名聚集索引) 不可作用于GUID类型字段,即:数据库中不要把GUID类型作为主键或设置为聚集索引. 聚集索引:索引的物理存储顺序与数据表中行数据物理存储顺序一致(索引存储物理有序). 非聚 ...
- SQL SERVER 聚集索引 非聚集索引 区别
转自http://blog.csdn.net/single_wolf_wolf/article/details/52915862 一.理解索引的结构 索引在数据库中的作用类似于目录在书籍中的作用,用来 ...
- SQLSERVER聚集索引与非聚集索引的再次研究(上)
SQLSERVER聚集索引与非聚集索引的再次研究(上) 上篇主要说聚集索引 下篇的地址:SQLSERVER聚集索引与非聚集索引的再次研究(下) 由于本人还是SQLSERVER菜鸟一枚,加上一些实验的逻 ...
- SQLSERVER聚集索引与非聚集索引的再次研究(下)
SQLSERVER聚集索引与非聚集索引的再次研究(下) 上篇主要说了聚集索引和简单介绍了一下非聚集索引,相信大家一定对聚集索引和非聚集索引开始有一点了解了. 这篇文章只是作为参考,里面的观点不一定正确 ...
- SQL Server 2014新特性探秘(3)-可更新列存储聚集索引
简介 列存储索引其实在在SQL Server 2012中就已经存在,但SQL Server 2012中只允许建立非聚集列索引,这意味着列索引是在原有的行存储索引之上的引用了底层的数据,因此会 ...
- [翻译] 聚集索引表 VS 堆表
前言: 本文对这篇博客Clustered Tables vs Heap Tables 的翻译, 如有翻译不对或不好的地方,敬请指出,大家一起学习进步. 问题描述 创建一个新表时,一个非常重要的设计原则 ...
- Sql Server之旅——第三站 解惑那些背了多年聚集索引的人
说到聚集索引,我想每个码农都明白,但是也有很多像我这样的猥程序员,只能用死记硬背来解决这个问题,什么表中只能建一个聚集索引, 然后又扯到了目录查找来帮助读者记忆....问题就在这里,我们不是学文科,, ...
随机推荐
- QT学习记录之环境搭建
作者:朱金灿 来源:http://blog.csdn.net/clever101 1. 安装qt-win-opensource-4.8.5-vs2008.exe(对应的IDE是VS2008),安装路径 ...
- Android 延时执行的几种方法
开启新线程 new Thread(new Runnable(){ public void run(){ Thread.sleep(XXXX); handler.sendMessage(); //告诉主 ...
- Mina框架项目运用
近期最一个项目对通信要求比較严格,须要建立长连接,且能处理多并发,所以选择了Mina框架.以下就简单记录开发的过程吧: mina 开发须要的jar包: mina pc端通信: 服务端: package ...
- Graphics-Processing Architecture Based on Approximate Rendering
BACKGROUND The present invention generally relates to the processing of graphics data, and particula ...
- 【hdu 2376】Average distance
[题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=2376 [题意] 让你计算树上任意两点之间的距离的和. [题解] 算出每条边的两端有多少个节点设为n ...
- mac下装php5.6
OS X10.11自带了php5.5,项目中使用的是php5.6,用brew install --without-apache --with-fpm --with-mysql php56装php5.6 ...
- Acdreamoj1116(Gao the string!)弦hash+二分法+矩阵高速功率
Problem Description give you a string, please output the result of the following function mod 100000 ...
- WPF--动态添加控件、访问控件
//WPF窗口采用默认的Grid布局控件,其“Name”值为“grid1”,在“grid1”中添加三个Button按钮.动态添加控件并访问这些控件的代码如下: private void button1 ...
- eclipse中让关闭的项目不再显示
- (让你提前知道软件开发33):数据操纵语言(DML)
文章2部分 数据库SQL语言 数据操纵语言(DML) 数据操纵语言(Data Manipulation Language,DML)包含insert.delete和update语句,用于增.删.改数据. ...