Chính xác thì null làm gì hiệu suất và lưu trữ (không gian) khôn ngoan trong MySQL?
Ví dụ:
TINYINT: 1 Byte TINYINT w / NULL 1 byte + bằng cách nào đó lưu trữ NULL?
Câu trả lời:
Nó phụ thuộc vào công cụ lưu trữ mà bạn sử dụng.
Ở định dạng MyISAM, mỗi tiêu đề hàng chứa một trường bit với một bit cho mỗi cột để mã hóa trạng thái NULL. Cột NULL vẫn chiếm dung lượng, vì vậy NULL không làm giảm bộ nhớ. Xem https://dev.mysql.com/doc/internals/en/myisam-introduction.html
Trong InnoDB, mỗi cột có một "độ lệch đầu trường" trong tiêu đề hàng, là một hoặc hai byte cho mỗi cột. Bit cao trong trường đó bù bắt đầu được bật nếu cột là NULL. Trong trường hợp đó, cột không cần phải được lưu trữ. Vì vậy, nếu bạn có nhiều NULL, dung lượng lưu trữ của bạn sẽ giảm đáng kể. Xem https://dev.mysql.com/doc/internals/en/innodb-field-contents.html
BIÊN TẬP:
Các bit NULL là một phần của tiêu đề hàng, bạn không chọn thêm chúng.
Cách duy nhất tôi có thể tưởng tượng NULL cải thiện hiệu suất là trong InnoDB, một trang dữ liệu có thể phù hợp với nhiều hàng hơn nếu các hàng chứa NULL. Vì vậy, bộ đệm InnoDB của bạn có thể hiệu quả hơn.
Nhưng tôi sẽ rất ngạc nhiên nếu điều này mang lại một lợi thế hiệu suất đáng kể trong thực tế. Lo lắng về ảnh hưởng của NULL đối với hiệu suất là trong lĩnh vực tối ưu hóa vi mô. Bạn nên tập trung sự chú ý của mình ở nơi khác, vào những khu vực mang lại tiếng vang lớn hơn cho đồng tiền. Ví dụ: thêm các chỉ mục được chọn tốt hoặc tăng phân bổ bộ nhớ cache cơ sở dữ liệu.
Câu trả lời của Bill là tốt, nhưng hơi lỗi thời. Việc sử dụng một hoặc hai byte để lưu trữ NULL chỉ áp dụng cho định dạng hàng InnoDB REDUNDANT. Vì MySQL 5.0.3 InnoDB sử dụng COMPACT định dạng hàng chỉ sử dụng một bit để lưu trữ NULL (tất nhiên một byte là tối thiểu), do đó:
Không gian cần thiết cho NULLs = CEILING (N / 8) byte trong đó N là số cột NULL trong một hàng.
Theo trang web MySQL chính thức về COMPACT vs REDUNDANT:
Định dạng hàng nhỏ gọn làm giảm không gian lưu trữ hàng khoảng 20% với chi phí tăng mức sử dụng CPU cho một số hoạt động. Nếu khối lượng công việc của bạn là một khối lượng công việc điển hình bị giới hạn bởi tốc độ truy cập bộ nhớ cache và tốc độ ổ đĩa, thì định dạng nhỏ gọn có thể sẽ nhanh hơn.
Bạn bắt đầu thấy khoản tiết kiệm ở đây:
Mặt khác, tôi khuyên bạn nên sử dụng NULL trên các chuỗi trống hoặc số không, vì chúng có tổ chức hơn, di động hơn và yêu cầu ít dung lượng hơn. Để cải thiện hiệu suất và tiết kiệm dung lượng, hãy tập trung vào việc sử dụng các loại dữ liệu, chỉ mục và truy vấn thích hợp thay vì các thủ thuật kỳ lạ.
Thêm trên: https://dev.mysql.com/doc/refman/5.7/en/innodb-physical-record.html
Tôi sẽ đồng ý với Bill Karwin, mặc dù tôi sẽ thêm các mẹo MySQL này . Số 11 đề cập cụ thể điều này:
Trước hết, hãy tự hỏi xem có sự khác biệt nào giữa việc có giá trị chuỗi rỗng so với giá trị NULL (đối với trường INT: 0 so với NULL) hay không. Nếu không có lý do gì để có cả hai, bạn không cần trường NULL. (Bạn có biết rằng Oracle coi chuỗi NULL và chuỗi rỗng giống nhau không?)
Các cột NULL yêu cầu thêm không gian và chúng có thể thêm phức tạp vào các câu lệnh so sánh của bạn. Chỉ cần tránh chúng khi bạn có thể. Tuy nhiên, tôi hiểu một số người có thể có những lý do rất cụ thể để có giá trị NULL, điều này không phải lúc nào cũng là điều xấu.
Mặt khác, tôi vẫn sử dụng null trên các bảng không có hàng tấn, chủ yếu là vì tôi thích logic của việc nói KHÔNG ĐỦ.
Cập nhật Xem lại điều này sau, tôi muốn nói thêm rằng cá nhân tôi không thích sử dụng 0 thay vì NULL trong cơ sở dữ liệu và tôi không khuyên bạn nên sử dụng nó. Điều này có thể dễ dàng dẫn đến rất nhiều kết quả dương tính giả trong ứng dụng của bạn nếu bạn không cẩn thận.
dev.mysql.com/doc/refman/5.0/en/is-null-optimization.html
MySQL có thể thực hiện tối ưu hóa tương tự trên col_name IS NULL mà nó có thể sử dụng cho col_name = const_value. Ví dụ: MySQL có thể sử dụng chỉ mục và phạm vi để tìm kiếm NULL với IS NULL