newid()和newsequentialid() 的區別

來源:互聯網
上載者:User

1.:newsequentialid 函數比起 newid 函數最大的好處是:如果你在一個 UNIQUEIDENTIFIER 欄位上建立索引,使用 newid 產生的新的值是不固定的,所以新的值導致索引B+樹的變化是隨機的。而 newsequentialid 產生的新的值是有規律的,則索引B+樹的變化是有規律的。有規律和無規律就會帶來效能的改進。

 

2:UNIQUEIDENTIFIER做主鍵(Primary Key)是一件很方便的事情,在資料合併等操作中有不可替代的優勢
但是由於普通的GUID的分散性使得如果主鍵加上叢集索引(Clustered Index)會導致在插入記錄時效率大大降低

SQL SERVER 2005中新增了一個NEWSEQUENTIALID的函數,MSDN的解釋是:
在指定電腦上建立大於先前通過該函數產生的任何 GUID 的 GUID。
NEWSEQUENTIALID() 不能在查詢中引用。
註:即只能做為資料庫列的DEFAULT VALUE,不能執行類似SELECT NEWSEQUENTIALID()的語句
只有當電腦沒有網卡時,NEWSEQUENTIALID() 產生的 GUID 才在該特定電腦中是唯一的。
註:這句話是錯誤的,應該是只有只有當電腦有網卡時,產生的GUID才是全球唯一
您可以使用 NEWSEQUENTIALID() 產生 GUID 以減少分葉層級索引上的頁爭用。

 

使用例子:

create table #dd
(
fid uniqueidentifier NULL  DEFAULT (NEWSEQUENTIALID()),
 fname [nvarchar](20))

 

insert into #dd(fname)values('dddff')

 

select * from #dd where fid > 'D8407C7D-0E7C-DE11-94B0-001A4DDD5F17' and fid<'E2507993-0E7C-DE11-94B0-001A4DDD5F17'

 

 

但是使用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        {
 8            const int RPC_S_OK = 0;
 9
10            Guid guid;
11            int result = UuidCreateSequential(out guid);
12            if (result != RPC_S_OK)
13           {
14                throw new ApplicationException("Create sequential guid failed: " + result);
15            }
16
17            return guid;
18        }
19    }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.