2012-10-30 39 views
50

Tôi đã tạo một ứng dụng trong Rails trên Heroku bằng cơ sở dữ liệu PostgreSQL.UUID có phải là khóa chính trong PostgreSQL cung cấp hiệu suất chỉ mục không tốt?

Nó có một vài bảng được thiết kế để có thể đồng bộ hóa với thiết bị di động nơi dữ liệu có thể được tạo ở những nơi khác nhau. Do đó tôi có một trường uuid là một chuỗi lưu trữ GUID ngoài khóa chính tăng tự động. Uuid là cái được truyền thông giữa máy chủ và máy khách.

Tôi nhận ra sau khi triển khai công cụ đồng bộ hóa ở phía máy chủ điều này dẫn đến vấn đề hiệu suất khi cần ánh xạ giữa uuid < -> id mọi lúc (khi viết đối tượng, tôi cần truy vấn uuid để lấy id trước khi lưu và ngược lại khi gửi lại dữ liệu).

Tôi hiện đang suy nghĩ về việc chuyển sang chỉ sử dụng UUID làm khóa chính giúp việc viết và đọc đơn giản hơn và nhanh hơn nhiều.

Tôi đã đọc UUID đó làm khóa chính đôi khi có thể cho hiệu suất chỉ mục xấu (phân mảnh chỉ mục) khi sử dụng chỉ mục khóa chính được nhóm. Có PostgreSQL bị vấn đề này hoặc là nó OK để sử dụng UUID là khóa chính?

Tôi đã có một cột UUID ngày hôm nay để lưu trữ khôn ngoan nó sẽ tốt hơn vì tôi thả cột id thông thường.

+2

Trường 'id' có được sử dụng như khóa ngoài bởi bất kỳ quan hệ nào khác trong cơ sở dữ liệu không? Bạn chỉ giữ trường 'id' này xung quanh vì bạn tin rằng PRIMARY KEY phải là loại nối tiếp vì những lý do bạn đã mô tả? –

+0

Clustering bằng khóa chính tổng hợp chỉ là một lợi ích nếu bạn có một con đường truy cập thường xuyên mà muốn truy vấn một loạt các giá trị pkey - đó là khá hiếm trong thế giới thực. UUID là một loại hoàn toàn tốt cho khóa chính, nó đủ nhỏ gọn (16bytes) và nhanh hơn so với op so với kiểu văn bản. – dbenhur

+0

@Joshua Các trường id được sử dụng như khóa ngoài, các trường UUID chỉ được sử dụng như các trường thông thường được sử dụng để tham chiếu các mối quan hệ khi giao tiếp (mà cần phải dịch giữa chúng mọi lúc) – thejaz

Trả lời

55

(Tôi làm việc trên Heroku Postgres)

Chúng tôi sử dụng UUID làm khóa chính trên một vài hệ thống và hoạt động tốt.

tôi khuyên bạn nên sử dụng phần mở rộng uuid-ossp, và thậm chí đã postgres tạo UUIDs cho bạn:

heroku pg:psql 
psql (9.1.4, server 9.1.6) 
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256) 
Type "help" for help. 

dcvgo3fvfmbl44=> CREATE EXTENSION "uuid-ossp"; 
CREATE EXTENSION 
dcvgo3fvfmbl44=> CREATE TABLE test (id uuid primary key default uuid_generate_v4(), name text); 
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index "test_pkey" for table "test" 
CREATE TABLE 
dcvgo3fvfmbl44=> \d test 
       Table "public.test" 
Column | Type |    Modifiers    
--------+------+------------------------------------- 
id  | uuid | not null default uuid_generate_v4() name | text | 
Indexes: 
    "test_pkey" PRIMARY KEY, btree (id) 

dcvgo3fvfmbl44=> insert into test (name) values ('hgmnz'); 
INSERT 0 1 
dcvgo3fvfmbl44=> select * from test; 
        id     | name 
--------------------------------------+------- 
e535d271-91be-4291-832f-f7883a2d374f | hgmnz 
(1 row) 

tác động hiệu suất EDIT

Nó sẽ luôn phụ thuộc vào khối lượng công việc của bạn.

Khoá chính nguyên có lợi thế về vị trí nơi dữ liệu giống như nằm gần nhau hơn. Điều này có thể hữu ích cho ví dụ: truy vấn loại dải ô như WHERE id between 1 and 10000 mặc dù tranh chấp khóa kém hơn.

Nếu khối lượng công việc đọc của bạn là hoàn toàn ngẫu nhiên mà bạn luôn thực hiện tra cứu khóa chính, không nên có bất kỳ sự suy giảm hiệu suất có thể đo lường nào: bạn chỉ trả cho loại dữ liệu lớn hơn.

Bạn có viết rất nhiều vào bảng này không và bảng này có lớn không? Có thể, mặc dù tôi đã không đo lường điều này, rằng có những hàm ý trong việc duy trì chỉ số đó. Đối với rất nhiều bộ dữ liệu UUID chỉ là tốt mặc dù, và bằng cách sử dụng UUID như định danh có một số thuộc tính tốt đẹp.

Cuối cùng, tôi có thể không phải là người đủ điều kiện nhất để thảo luận hoặc tư vấn về điều này, vì tôi chưa bao giờ chạy một bảng đủ lớn với một PK UUID nơi nó đã trở thành một vấn đề. YMMV. (Có nói rằng, tôi rất muốn nghe những người gặp vấn đề với cách tiếp cận này!)

+0

Cảm ơn bạn đã phản hồi. Tôi đang tạo ra các UUID trong các mô hình Rails ngày hôm nay, đó là chỉ là tốt như sử dụng chức năng cơ sở dữ liệu ở trên? – thejaz

+0

Có, tôi thấy không có vấn đề với điều đó miễn là các mô hình đường ray của bạn là điều duy nhất chèn dữ liệu vào cơ sở dữ liệu của bạn. – hgmnz

+0

@hgmnz: Làm cách nào để bạn xác định cột id là uuid thông qua di chuyển Rails? –

1

Khi trạng thái câu trả lời được chấp nhận, truy vấn phạm vi có thể chậm trong trường hợp này, nhưng không chỉ trên id.

Tự động sắp xếp tự động được sắp xếp theo ngày, do đó khi tự động được sử dụng, dữ liệu được lưu trữ theo thứ tự thời gian trên đĩa (xem B-Tree) để tăng tốc độ đọc (không tìm kiếm ổ cứng).Ví dụ, nếu một danh sách tất cả người dùng thứ tự tự nhiên sẽ theo ngày tạo ra giống như tự động sắp xếp và vì vậy các truy vấn phạm vi thực thi nhanh hơn trên HDD trong khi trên SSD, tôi đoán, sự khác biệt sẽ không tồn tại kể từ SSD. truy cập (không có đầu tìm kiếm, không có bộ phận cơ khí nào liên quan, chỉ điện thuần túy)

Các vấn đề liên quan