2017-06-20 24 views
6

Nếu tôi hiểu chính xác, các giá trị UUID hoàn toàn ngẫu nhiên sẽ tạo ra các chỉ mục bị phân mảnh. Hoặc, chính xác hơn, việc thiếu một tiền tố chung ngăn chặn lưu trữ trie dày đặc trong các chỉ mục.Tạo UUID không phân đoạn trong Postgres?

Tôi đã thấy đề xuất sử dụng uuid_generate_v1() hoặc uuid_generate_v1mc() thay vì uuid_generate_v4() để tránh sự cố này.

Tuy nhiên, có vẻ như Phiên bản 1 của thông số UUID có các bit thấp trước tiên của ID, ngăn chặn tiền tố được chia sẻ. Ngoài ra, dấu thời gian này là 60 bit, có vẻ như nó có thể quá mức cần thiết.

Ngược lại, một số cơ sở dữ liệu cung cấp máy phát UUID không chuẩn với dấu thời gian trong 32 bit đầu tiên và sau đó là 12 byte ngẫu nhiên. Xem Squomid của Datomic ví dụ 1, 2.

Thực tế có ý nghĩa khi sử dụng "Squuids" như thế này trong Postgres không? Nếu vậy, làm thế nào tôi có thể tạo ID như vậy một cách hiệu quả với pgplsql?

+0

Như bạn chèn hoặc cập nhật dữ liệu nhiều hơn, bạn có thể nhận được các chỉ số phân mảnh, có nghĩa là B + Tree, nếu bạn đang sử dụng một chỉ số bình thường, ít cân bằng hơn. Tất nhiên bạn có thể reindex để làm cho cây cân bằng hơn. Từ câu hỏi của bạn, tôi giả định rằng bạn muốn xem phiên bản UUID nào được cây cân bằng hơn. Tôi nghĩ bạn nên chạy một số điểm chuẩn bằng cách sử dụng [pgbench] (https://www.postgresql.org/docs/devel/static/pgbench.html) để xem liệu có sự khác biệt về chi phí hiệu suất và nếu kế hoạch được tạo tốt. Nếu bất kỳ giải pháp nào phù hợp với ứng dụng của bạn thì phần còn lại hoàn toàn là nghiên cứu học thuật. – andreim

+0

_prevents lưu trữ trie dày đặc trong indexes_: tại sao giả sử lưu trữ trie? Thông thường, bạn sẽ sử dụng chỉ mục B-tree cho UUID. Bạn sẽ nhận được bộ nhớ trie chỉ khi yêu cầu nó, thông qua họ điều hành 'text_ops' của chỉ mục' SP-GiST'. –

Trả lời

1

Lưu ý rằng việc chèn các mục nhập chỉ mục tuần tự sẽ dẫn đến chỉ mục đậm đặc hơn nếu bạn không xóa các giá trị và tất cả các bản cập nhật của bạn tạo ra heap only tuples.

Nếu bạn muốn giá trị chỉ mục duy nhất tuần tự, tại sao bạn không tự xây dựng chúng?

Bạn có thể sử dụng clock_timestamp() trong nano giây như bigint và nối các giá trị từ một chuỗi đi xe đạp:

CREATE SEQUENCE seq MINVALUE 0 MAXVALUE 999 CYCLE; 

SELECT CAST(
      floor(
      EXTRACT(epoch FROM t) 
     ) AS bigint 
     ) % 1000000 * 1000000000 
    + CAST(
      to_char(t, 'US') AS bigint 
     ) * 1000 
    + nextval('seq') 
FROM (SELECT clock_timestamp()) clock(t);