NULL trong MySQL (Hiệu suất & Lưu trữ)


77

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:


103

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.


Thêm một bit NULL có làm tăng tốc độ tìm kiếm không? (So ​​với việc chỉ để trống sân)
Steve

1
Xem nội dung bổ sung sau khi "EDIT" trong nhận xét của tôi ở trên.
Bill Karwin 24/10/08

4
@Performance: Nếu bạn có chỉ mục trên một cột, đó là NULL, MySQL cần logic hơn để chọn, sắp xếp, v.v. Vì vậy, tôi khuyên bạn nên tránh NULL ít nhất cho các trường được lập chỉ mục vì lý do hiệu suất.
Phil

@BillKarwin On mysql Trang web chính thức họ đề cập Không Null là tốt hơn trong hoạt động và kích thước dev.mysql.com/doc/refman/5.5/en/data-size.html
Navrattan Yadav

@navy, tôi khuyến khích bạn thực hiện một số điểm chuẩn để xác nhận sự khác biệt nhiều hay ít giữa việc sử dụng null hay không null.
Bill Karwin,

40

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.

  • 0 NULLS = 0 byte
  • 1-8 NULLS = 1 byte
  • 9-16 NULLS = 2 byte
  • 17-24 NULLS = 3 byte
  • Vân vân...

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.

Lợi thế của việc sử dụng NULLS trên Chuỗi trống hoặc Zeros:

  • 1 NULL yêu cầu 1 byte
  • 1 Chuỗi trống yêu cầu 1 byte (giả sử VARCHAR)
  • 1 Zero yêu cầu 4 byte (giả sử INT)

Bạn bắt đầu thấy khoản tiết kiệm ở đây:

  • 8 NULL yêu cầu 1 byte
  • 8 Chuỗi trống yêu cầu 8 byte
  • 8 Zeros yêu cầu 32 byte

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


vì vậy như tôi đã hiểu từ câu trả lời của bạn, tối ưu hóa được nhúng trong Mysql? và tôi không nên làm gì cả, chỉ sử dụng mysql 5.0.3 trở lên là đủ?
Ammar Bozorgvar

@ ammar-bozorgvar Có, những điều này được thực hiện nội bộ bởi MySQL theo mặc định khi sử dụng InnoDB. Đây là liên kết tài liệu chính thức . Chúc may mắn!
Arian Acosta

Tôi hơi bối rối: Bill nói rằng "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à bạn nói "8 NULL yêu cầu 1 byte ". Null có chiếm dung lượng hay không? Cảm ơn
bylijinnan

1
Bây giờ tôi hiểu: 8 NULL yêu cầu 1 byte TRONG ĐẦU GHI HÌNH, nhưng NULL không được lưu trữ.
bylijinnan

6

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.


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.