2014-09-22 81 views
3

在表中插入新記錄時,可以有兩種方法,一種是找到主鍵列的最大值並向其添加1或使用序列。哪種方法更好,爲什麼?序列vs最大主鍵值+ 1

如果我們通過遞增表中主鍵列的最大值小於20,000條記錄來找到下一個主鍵值,會產生什麼影響?

謝謝。

+8

提示:嘗試在多用戶環境中的最高值的方法,你會發現爲什麼使用順序是正確的方法。 – 2014-09-22 18:41:00

+2

我建議你使用序列。成本做一次nextval將永遠低於做了最大的操作 – Aramillo 2014-09-22 18:43:31

+3

系列化(鎖定造成的等待)肯定是缺點的最大主鍵+ 1分的方式。 – 2014-09-22 18:43:56

回答

12

問:哪種方法更好,爲什麼?

- 答:使用SEQUENCE對象是一種更好的方法。

MAX(id)+1方法來獲得價值獨特 ID是在多線程環境中,不存在併發殺破鎖。這個問題不會在單用戶測試中暴露出來;但使用兩個不同的會話很容易證明這一點。考慮這樣的操作順序:

會話1:SELECT MAX(id)+1 AS next_id FROM mytable - > 42

會話2:SELECT MAX(id)+1 AS next_id FROM mytable - > 42

會話1:INSERT INTO mytable (id) VALUES (42)

會話2:INSERT INTO mytable (id) VALUES (42)

爲了防止兩個(或更多)單獨的會話返回相同的值next_id,會話必須獲得排它鎖它執行查詢之前的表。它還需要保持該鎖定,直到在將該值插入表格之前,在釋放鎖定之前。雖然該會話在表上保留排它鎖,但其他會話不能查詢或插入表中,如果其他會話嘗試執行,則會阻止其他會話。 (我們不希望通過引入這種鎖定來殺死數據庫性能,這不是正確的方法,所以我們不打算演示如何完成。)

Oracle提供了SEQUENCE對象作爲高效用於獲得唯一值的方法,針對SEQUENCE對象的查詢在多線程環境中是「安全的」。對於高負載下的性能,我們會增加序列的「緩存」值,即內存中可用值的數量,這樣我們就可以滿足更多的NEXTVAL請求,而不需要寫入重做日誌。

鑑於這兩種選擇,SEQUENCE是更好的方法。


問:什麼影響,如果我們發現通過在具有小於20,000條記錄表增加主鍵列的最大值的下一個主鍵值?

一個:檢索索引列的最大值(也就是在一個索引的前導列的列),以及添加一個到它的查詢,應該是很有效的,因爲只要會話是能夠獲得所需的共享鎖(即會話不被排他鎖鎖定)。)