Tôi có nên đầu tư thời gian để thay đổi loại cột từ CHAR (36) thành UUID không?


14

Tôi đã có một vài triệu hàng trong cơ sở dữ liệu của mình rồi. Tôi không biết về kiểu dữ liệu UUID của PostgreSQL khi tôi thiết kế lược đồ của mình.

Một trong các bảng có 16M hàng (khoảng 3,5M đến 4 M bản ghi mỗi phân đoạn), tăng khoảng 500 nghìn bản ghi mỗi ngày. Tôi vẫn có thể sử dụng hệ thống sản xuất trong vài giờ nếu cần thiết. Tôi sẽ không có sự sang trọng này trong một hoặc hai tuần.

Câu hỏi của tôi là, nó sẽ có giá trị để làm như vậy? Tôi đang tự hỏi về hiệu suất THAM GIA, sử dụng dung lượng ổ đĩa (toàn bộ gzip'd là 1,25 GiB), những thứ thuộc về bản chất đó.

Lược đồ bảng là:

# \d twitter_interactions
                Table "public.twitter_interactions"
         Column          |            Type             | Modifiers 
-------------------------+-----------------------------+-----------
 interaction_id          | character(36)               | not null
 status_text             | character varying(1024)     | not null
 screen_name             | character varying(40)       | not null
 twitter_user_id         | bigint                      | 
 replying_to_screen_name | character varying(40)       | 
 source                  | character varying(240)      | not null
 tweet_id                | bigint                      | not null
 created_at              | timestamp without time zone | not null
Indexes:
    "twitter_interactions_pkey" PRIMARY KEY, btree (interaction_id)
    "twitter_interactions_tweet_id_key" UNIQUE, btree (tweet_id)
    "index_twitter_interactions_on_created_at" btree (created_at)
    "index_twitter_interactions_on_screen_name" btree (screen_name)
Triggers:
    insert_twitter_interactions_trigger BEFORE INSERT ON twitter_interactions FOR EACH ROW EXECUTE PROCEDURE twitter_interactions_insert_trigger()
Number of child tables: 9 (Use \d+ to list them.)

Câu trả lời:


13

Tôi sẽ xem xét thay đổi sang loại UUID. char(36)mất 40 byte, uuidmất 16 byte, vì vậy bạn sẽ tiết kiệm được 24 byte mỗi hàng, với bạn sẽ tương đương với 12 MB mỗi ngày, 4 GB sau một năm. Chỉ số cộng. Tùy thuộc vào phần cứng bạn có, điều đó không nhiều, nhưng nó có thể. Và nó cộng lại nếu bạn có nhiều cơ hội cải tiến như thế này.

Ngoài ra, tôi thấy không có ràng buộc nào trong lược đồ của bạn đảm bảo rằng interaction_idnó thực sự ở định dạng đúng. Sử dụng đúng loại cũng sẽ cung cấp cho bạn điều đó.

Tuy nhiên, nếu bạn thích điều này, hơn là sử dụng bigintsẽ tiết kiệm hơn nữa và có hiệu suất cao hơn. Rất có khả năng ứng dụng của bạn quá lớn đến nỗi một bigintcột ID sẽ không hoạt động.


Tôi có một hệ thống phân tán: nhiều nguồn dữ liệu tạo ID cho các tương tác, do đó tôi không thể sử dụng BIGINT trừ khi tôi dành riêng N bit cho ID nút.
François Beausoleil

3
@ FrançoisBeausoleil, dự trữ N bit cho ID nút bằng với việc sử dụng mọi số N trong chuỗi (và do đó dễ thực hiện). Ngoài ra, bạn có thể xem xét sử dụng các phím tổng hợp.
Không hợp lý

1
Phối hợp nhiều chuỗi (với ID nút) là một rắc rối quản trị trong thực tế và dễ bị lỗi của con người. Tôi thấy không có lý do gì để không sử dụng UUID trong kịch bản này, đặc biệt là các bit hiện nay rất rẻ (cả bộ nhớ và lưu trữ). Thật vậy, kịch bản này là lý do chính các UUID được phát minh từ nhiều thập kỷ trước: Để chia sẻ dữ liệu giữa các hệ thống phân tán mà không cần phối hợp tập trung .
Basil Bourque

6

Tôi không phải là người thích khám phá trí tưởng tượng, nhưng dựa trên những gì tôi biết từ SQL Server, bạn càng có nhiều hàng phù hợp với trang dữ liệu, bạn sẽ có hiệu suất tốt hơn (thường đọc dữ liệu từ đĩa hoạt động tốn kém nhất). Do đó, đi từ trường rộng 36 ish 1 byte sang GUID 16 byte có vẻ tiết kiệm chi phí thẳng. Bạn càng đọc ít, bạn càng có thể trả về kết quả nhanh hơn. Tất cả điều này tất nhiên giả định rằng GUID / UUID đáp ứng nhu cầu kinh doanh của bảng. Nếu đáp ứng UUID nó, sẽ là một bigint ? Điều đó sẽ tiếp tục cạo bộ nhớ của bạn tốn thêm 8 byte mỗi hàng.

Chỉnh sửa 1

Đối với dữ liệu ký tự trong Postgres, có thêm chi phí lưu trữ cho chúng. Các chuỗi ngắn, dưới 127 byte có chi phí 1 byte trong khi bất kỳ thứ gì dài hơn có 4 byte, đó là cách người trả lời thứ hai đưa ra chi phí 40 byte cho trường 36 byte. Nhưng cũng có một tùy chọn để nén chuỗi nên có lẽ nó sẽ không tốn đủ 40. Tôi không thể biết chi phí cuối cùng sẽ là bao nhiêu nhưng nguyên tắc cơ bản vẫn là: mọi thứ trên 16 byte sẽ tăng chi phí lưu trữ, mất nhiều thời gian hơn để đọc và tiêu thụ nhiều bộ nhớ hơn.

Yêu cầu lưu trữ cho một chuỗi ngắn (tối đa 126 byte) là 1 byte cộng với chuỗi thực tế, bao gồm phần đệm không gian trong trường hợp ký tự. Chuỗi dài hơn có 4 byte phí thay vì 1. Chuỗi dài được hệ thống nén tự động, do đó yêu cầu vật lý trên đĩa có thể ít hơn.


3

Bên cạnh vấn đề về không gian, hãy nhớ rằng bạn sẽ cần thay đổi mỗi bảng để sử dụng đúng loại dữ liệu hoặc hiệu suất tham gia của bạn sẽ tăng lên.


Đó là một cho, nhưng cảm ơn vì đã nhắc nhở tôi.
François Beausoleil

3
Khi thực hiện những thay đổi lớn như thế này, tôi thấy rằng việc viết ra mọi thứ (dù điều đó có đơn giản đến mức nào để nhớ) thường sẽ được đền đáp.
mrdenny

3

Ngoài việc tiết kiệm kích thước của dữ liệu và chỉ mục (như đã nói của người khác), dịch chuyển sang tiết kiệm I / O, điều bạn cần xem xét là bạn sẽ tạo ra các giá trị mới như thế nào interaction_idvà điều gì sẽ tác động đến chỉ mục và điều kiện truy vấn (tham gia).

Đối với chỉ mục - nó sẽ nhỏ hơn, tuy nhiên nếu nhiều truy vấn của bạn sử dụng quét chỉ mục chuyển sang UUID có thể khiến quét chỉ mục không thể (tùy thuộc vào cách bạn sẽ tạo UUID) và bigint có thể là lựa chọn tốt hơn nhiều.

Cuối cùng, do tác động hiệu suất thực tế cũng phụ thuộc vào mô hình sử dụng phân phối dữ liệu của bạn, bạn nên chạy thử nghiệm và có môi trường phát triển và thử nghiệm để bạn có thể kiểm tra các thay đổi của mình.

Điều này sẽ cung cấp cho bạn một câu trả lời chính xác hơn nhiều về tác động đến hiệu suất.


Cảm ơn sự đóng góp hữu ích và chào mừng đến với trang web :)
Jack Douglas

Các mẫu truy cập của tôi thông qua các phạm vi ngày, THAM GIA bằng cách sử dụng screen_name hoặc bằng UUID. Không có phạm vi quét trên ID duy nhất được dự đoán. Cảm ơn câu trả lời của bạn, rất nhiều thông tin.
François Beausoleil
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.