PostgreSQL 9.3 中的非順序主鍵性能
由於需要支持分佈式環境,我的每個客戶端都被分配了唯一的節點 ID,它將帶有執行號的節點 ID 附加為主鍵並儲存在本地數據庫中。例如
Client A 節點 id = 200,表中第一行的主鍵為 200,000
客戶端 B 節點 id = 100,表中第一行的主鍵為 100,000
然後這些記錄複製到集中式數據庫。由於中心化數據庫的主鍵不是按順序排列的,當數據量變大時會不會引起嚴重的性能問題?
在集中式數據庫中插入新數據的可能順序:
200,000 100,000 100,001 200,001 300,000 100,002
這可能會導致 SQL Server 中的表沿著 PK 聚集的情況下出現很大的性能。但是,這會在 PostgreSQL 9.3 中發生嗎?
筆記:
- 我不能使用複合鍵,因為它在我的表示層上不能很好地播放。
- 3位數的流水號只是一個簡化的例子,真實的流水號會大得多,也足夠了。
我有3個解決方案給你:
直接引用序列並使用 concat
一種可能的解決方案是直接引用插入語句中的序列並預先添加您的節點 ID。一個類似的問題,包括你可以在這裡找到的答案: https ://stackoverflow.com/a/17925601/4206293
使用 UUID
另一種可能的解決方案是,如果您不需要主鍵欄位中的 node-id,您可以使用提供 uuid 類型和生成 uuid 的函式的 uuid-ossp 擴展:http://www.postgresql。 org/docs/9.4/static/uuid-ossp.html
為這些解決方案使用觸發器
對於這兩種解決方案:您可以使用觸發器來設置主鍵。
例子:
-- table CREATE TABLE test( id character varying(10) NOT NULL, "name" character varying, CONSTRAINT idx_pk PRIMARY KEY (id) ); -- seqence CREATE SEQUENCE test_seq INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1; -- Create Function CREATE OR REPLACE FUNCTION insert_trigger() RETURNS TRIGGER AS $$ BEGIN NEW.id := '100' || nextval('test_seq')::TEXT; RETURN NEW; END; $$ LANGUAGE 'plpgsql'; -- add Trigger CREATE TRIGGER insert_table_trigger BEFORE INSERT ON pkTable FOR EACH ROW EXECUTE PROCEDURE insert_trigger();
如果您現在在表中插入一個值
INSERT INTO test (name) VALUES ('test text');
你得到你的主鍵'1001'
使用 MINVALUE 和 MAXVALUE
另一種方法是使用 SEQUENCE 的 MINVALUE 和 MAXVALUE 來定義數字空間:
CREATE SEQUENCE node100_seq INCREMENT 1 MINVALUE 100000000000 MAXVALUE 100999999999 START 100000000000 CACHE 1; CREATE SEQUENCE node200_seq INCREMENT 1 MINVALUE 200000000000 MAXVALUE 200999999999 START 200000000000 CACHE 1;
復活!!這是一個舊執行緒,我認為現在仍然存在更多相同的問題和問題,因為人們擁有各種分佈式系統。關於問題中顯示的方法,我的 2c 對此:
200,000 100,000 100,001 200,001 300,000 100,002
這正是我前一天的想法,因為我有完全相同的問題。但即使我不認為這是一個數據庫性能問題,也有一個邏輯限制和假設,即第一個源中的記錄不會超過一百萬。(我想到了一個更大的數字,比如 20M)
因此,在環顧四周時,我發現了這個非常古老的 PG 論壇主題,我更喜歡後綴方法而不是前綴,因此新的 id 看起來像 node1:
101 201 301
對於節點 2
102 202 302
這為您提供了可能的 100 個節點(對於 1000 個節點,您始終可以使用 001,002 後綴)。
優點:
- 非常簡單的解決方案,與 PK 指數的差距更小
- 可以調整添加任意數量的節點
缺點:
- 這需要在將數據帶到中心節點時進行轉換
- 我不太贊成使用某些函式來生成這樣的 PK
但在我們的例子中,因為我們確實有其他轉換規則——我認為我們可以處理這個問題。