Một câu hỏi tương tự đã được hỏi trước đó
Ý nghĩa về hiệu suất của các kích thước VARCHAR của MySQL
Đây là đoạn trích câu trả lời của tôi
Bạn phải nhận ra sự đánh đổi bằng cách sử dụng CHAR vs VARCHAR
Với các trường CHAR, những gì bạn phân bổ chính xác là những gì bạn nhận được. Ví dụ: CHAR (15) phân bổ và lưu trữ 15 byte, bất kể bạn đặt ký tự trong trường như thế nào. Thao tác chuỗi rất đơn giản và dễ hiểu vì kích thước của trường dữ liệu là hoàn toàn có thể dự đoán được.
Với các trường VARCHAR, bạn có được một câu chuyện hoàn toàn khác. Ví dụ, VARCHAR (15) thực sự phân bổ động tối đa 16 byte, tối đa 15 cho dữ liệu và, ít nhất, thêm 1 byte để lưu trữ độ dài của dữ liệu. Nếu bạn có chuỗi 'hello' để lưu trữ sẽ mất 6 byte, chứ không phải 5. Thao tác chuỗi phải luôn thực hiện một số hình thức kiểm tra độ dài trong mọi trường hợp.
Sự cân bằng thể hiện rõ hơn khi bạn thực hiện hai điều: 1. Lưu trữ hàng triệu hoặc hàng tỷ hàng 2. Các cột lập chỉ mục là CHAR hoặc VARCHAR
TRADINGOFF # 1 Rõ ràng, VARCHAR nắm giữ lợi thế vì dữ liệu có độ dài thay đổi sẽ tạo ra các hàng nhỏ hơn và do đó, các tệp vật lý nhỏ hơn.
TRADINGOFF # 2 Vì các trường CHAR yêu cầu thao tác chuỗi ít hơn do độ rộng trường cố định, tra cứu chỉ mục so với trường CHAR trung bình nhanh hơn 20% so với trường VARCHAR. Đây không phải là bất kỳ phỏng đoán nào về phía tôi. Cuốn sách Thiết kế và điều chỉnh cơ sở dữ liệu MySQL đã thực hiện một cái gì đó tuyệt vời trên bảng MyISAM để chứng minh điều này. Ví dụ trong cuốn sách đã làm một cái gì đó như sau:
ALTER TABLE tblname ROW_FORMAT=FIXED;
Lệnh này buộc tất cả các VARCHAR hoạt động như CHARs. Tôi đã làm điều này trong công việc trước đây vào năm 2007 và lấy một bảng 300 GB và tăng tốc độ tra cứu chỉ số thêm 20% mà không thay đổi bất cứ điều gì khác. Nó làm việc như đã xuất bản. Tuy nhiên, nó đã tạo ra một bảng có kích thước gần gấp đôi, nhưng điều đó chỉ đơn giản là quay trở lại sự đánh đổi # 1.
Bạn có thể phân tích dữ liệu đang được lưu trữ để xem những gì MySQL đề xuất cho định nghĩa cột. Chỉ cần chạy như sau với bất kỳ bảng nào:
SELECT * FROM tblname PROCEDURE ANALYSE();
Điều này sẽ đi qua toàn bộ bảng và đề xuất các định nghĩa cột cho mỗi cột dựa trên dữ liệu chứa, các giá trị trường tối thiểu, giá trị trường tối đa, v.v. Đôi khi, bạn chỉ cần sử dụng thông thường với việc lập kế hoạch CHAR vs VARCHAR. Đây là một ví dụ tốt:
Nếu bạn đang lưu trữ địa chỉ IP, mặt nạ cho một cột như vậy nhiều nhất là 15 ký tự (xxx.xxx.xxx.xxx). Tôi sẽ nhảy ngay vào CHAR(15)
một nhịp tim vì độ dài của địa chỉ IP sẽ không thay đổi nhiều và độ phức tạp thêm của thao tác chuỗi được điều khiển bởi một byte bổ sung. Bạn vẫn có thể làm PROCEDURE ANALYSE()
một cột chống lại một cột như vậy. Nó thậm chí có thể đề nghị VARCHAR. Tiền của tôi sẽ vẫn còn trên CHAR trên VARCHAR trong trường hợp này.
Các vấn đề CHAR vs VARCHAR chỉ có thể được giải quyết thông qua kế hoạch thích hợp. Với sức mạnh lớn đi kèm với trách nhiệm lớn (sáo rỗng nhưng đúng).
CẬP NHẬT
Khi nói đến MD5, strlen
cần loại bỏ tính toán nội bộ khi chuyển đổi toàn bộ định dạng hàng. Sẽ không cần phải thay đổi định nghĩa trường.
Nếu khóa MD5 là VARCHAR duy nhất hiện tại, tôi sẽ tìm nó và chuyển đổi định dạng hàng của bảng thành cố định . Nếu có một số lượng đáng kể các trường VARCHAR khác, họ cũng sẽ được hưởng lợi. Đổi lại, bảng sẽ mở rộng gấp đôi kích thước của nó. Nhưng các truy vấn sẽ tăng tốc thêm khoảng 20% mà không cần điều chỉnh bổ sung.