Tôi đang phát triển một ứng dụng trong Ruby on Rails với cơ sở dữ liệu PostgreSQL (9.4). Đối với trường hợp sử dụng của tôi, các cột trong bảng sẽ được tra cứu rất thường xuyên, vì toàn bộ điểm của ứng dụng đang tìm kiếm các thuộc tính rất cụ thể trên một mô hình.
Tôi hiện đang quyết định có nên sử dụng một integer
loại hoặc đơn giản là sử dụng một loại chuỗi điển hình (ví dụ character varying(255)
, đó là mặc định trong Rails ) cho các cột, như tôi không chắc chắn những gì khác biệt hiệu suất sẽ được trên các chỉ số.
Những cột này là enum . Chúng có kích thước cố định cho số lượng giá trị có thể có. Hầu hết độ dài enum không vượt quá 5, có nghĩa là chỉ số sẽ được cố định ít nhiều trong suốt vòng đời của ứng dụng ; do đó, các chỉ số nguyên và chuỗi sẽ giống hệt nhau về số lượng nút.
Tuy nhiên, chuỗi được lập chỉ mục có thể dài khoảng 20 ký tự, trong bộ nhớ gần bằng 5x so với số nguyên (nếu số nguyên là 4 byte và chuỗi là ASCII thuần ở mức 1 byte cho mỗi ký tự, thì số này giữ). Tôi không biết làm thế nào các công cụ cơ sở dữ liệu thực hiện tra cứu chỉ mục, nhưng nếu nó cần "quét" chuỗi cho đến khi nó khớp chính xác , thì về bản chất, điều đó có nghĩa là việc tra cứu chuỗi sẽ chậm hơn 5x so với tra cứu số nguyên; "quét" cho đến khi khớp với tra cứu số nguyên sẽ là 4 byte thay vì 20. Đây là những gì tôi đang tưởng tượng:
Giá trị tra cứu là (số nguyên) 4:
quét ............................ FOUND | nhận hồ sơ ... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... |
Giá trị tra cứu là (chuỗi) "some_val" (8 byte):
quét ................................................. .................................... NỀN TẢNG | nhận hồ sơ ... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... |
Tôi hy vọng điều đó có ý nghĩa. Về cơ bản, vì số nguyên chiếm ít không gian hơn, nên nó có thể được "khớp trên" nhanh hơn so với đối tác chuỗi của nó. Có lẽ đây là một dự đoán hoàn toàn sai, nhưng tôi không phải là chuyên gia, vì vậy đó là lý do tại sao tôi hỏi các bạn! Tôi cho rằng câu trả lời này tôi vừa tìm thấy dường như ủng hộ giả thuyết của tôi, nhưng tôi muốn chắc chắn.
Số lượng giá trị có thể có trong cột sẽ không thay đổi khi sử dụng một trong hai, do đó, chính chỉ mục sẽ không thay đổi (trừ khi tôi đã thêm một giá trị mới vào enum). Trong trường hợp này, liệu có sự khác biệt về hiệu suất trong việc sử dụng integer
hoặc varchar(255)
, hoặc sử dụng một kiểu số nguyên có ý nghĩa hơn không?
Lý do tôi hỏi là enum
loại bản đồ của Rails có các số nguyên cho các chuỗi chuỗi, nhưng chúng không có nghĩa là các cột đối diện với người dùng. Về cơ bản, bạn không thể xác minh rằng giá trị enum là hợp lệ, bởi vì giá trị không hợp lệ sẽ gây ra ArgumentError
trước khi bất kỳ xác nhận nào có thể được chạy. Sử dụng một string
loại sẽ cho phép xác nhận, nhưng nếu có chi phí hiệu năng, tôi chỉ muốn khắc phục vấn đề xác nhận.
varchar(255)
vs ví dụvarchar(260)
. Có thể đã có một điều như vậy với SQL Server 6.x nhưng điều này đã không đúng trong một thời gian dài.