在表中插入新記錄時,可以有兩種方法,一種是找到主鍵列的最大值並向其添加1或使用序列。哪種方法更好,爲什麼?序列vs最大主鍵值+ 1
如果我們通過遞增表中主鍵列的最大值小於20,000條記錄來找到下一個主鍵值,會產生什麼影響?
謝謝。
在表中插入新記錄時,可以有兩種方法,一種是找到主鍵列的最大值並向其添加1或使用序列。哪種方法更好,爲什麼?序列vs最大主鍵值+ 1
如果我們通過遞增表中主鍵列的最大值小於20,000條記錄來找到下一個主鍵值,會產生什麼影響?
謝謝。
問:哪種方法更好,爲什麼?
- 答:使用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條記錄表增加主鍵列的最大值的下一個主鍵值?
一個:檢索索引列的最大值(也就是在一個索引的前導列的列),以及添加一個到它的查詢,應該是很有效的,因爲只要會話是能夠獲得所需的共享鎖(即會話不被排他鎖鎖定)。)
提示:嘗試在多用戶環境中的最高值的方法,你會發現爲什麼使用順序是正確的方法。 – 2014-09-22 18:41:00
我建議你使用序列。成本做一次nextval將永遠低於做了最大的操作 – Aramillo 2014-09-22 18:43:31
系列化(鎖定造成的等待)肯定是缺點的最大主鍵+ 1分的方式。 – 2014-09-22 18:43:56