Cách tối ưu hóa các bảng InnoDB trong MySQL


8

Tôi đã nghiên cứu cách tối ưu hóa chỉ các bảng phân mảnh trong MySQL và xem xét bài đăng này trên các bảng tối ưu hóa . Về cơ bản, nó thực hiện một truy vấn đối với cơ sở dữ liệu information_schema cho bất kỳ bảng nào data_free > 0và xây dựng một câu lệnh SQL OPTIMIZEchỉ cho các bảng đó. Tôi đã chạy truy vấn này và nó đã xác định 148 bảng để tối ưu hóa. Tất cả các bảng được xác định là các bảng InnoDB. Sau khi thực hiện tập lệnh SQL tối ưu hóa kết quả, tôi chạy lại tập lệnh gốc để xác định các bảng bị phân mảnh và nó trả về chính xác các bảng trong lần truyền đầu tiên.

Tôi đã thấy các bài viết mâu thuẫn về các bảng InnoDB và OPTIMIZElệnh. Một số người nói rằng OPTIMIZEsẽ không hoạt động với các bảng InnoDB và bạn cần phải chạy ALTER TABLE table_name ENGINE=INNODB. Những người khác nói rằng OPTIMIZEthực sự gọi ALTER TABLElệnh khi thực hiện đối với các bảng InnoDB. Với ý nghĩ đó, tôi đã chạy ALTER TABLElệnh chống lại một trong các bảng InnoDB được xác định là bị phân mảnh ( data_free > 0) và thấy rằng điều đó data_freekhông thay đổi sau đó. Nó vẫn lớn hơn 0. Tôi cũng khởi động lại MySQL và chỉ kiểm tra nó để tìm kết quả tương tự.

Bây giờ, chúng tôi có một số máy chủ chạy MySQL 5.5,29 trong tổ chức của chúng tôi và tôi đã chạy một truy vấn đối với tất cả chúng để xác định bất kỳ bảng InnoDB nào DATA_FREE=0 or NULLvà không có bảng nào được trả về. Tất cả đều lớn hơn không.

Tôi cũng đã chạy OPTIMIZElệnh đối với một vài MyISAMbảng có giá trị DATA_FREElớn hơn 0 và xác minh rằng nó bằng 0 sau đó.

Ai đó có thể làm sáng tỏ vấn đề này giúp tôi không? Phương pháp thích hợp để loại bỏ phân mảnh khỏi các bảng InnoDB là gì? Phương pháp thích hợp để xác định các bảng InnoDB bị phân mảnh là gì?

Cảm ơn

Câu trả lời:


9

Tôi sẽ cho rằng bạn đang sử dụng innodb_file_per_tablecho câu trả lời này.

Có nhiều hơn một nghĩa là "phân mảnh InnoDB":

  1. .ibd tập tin bị phân mảnh và rất lớn trong khi tập dữ liệu nhỏ
  2. Các trang chỉ mục bị phân mảnh trong đó có quá nhiều trang chứa ít dữ liệu, trong trường hợp đó chúng có thể được hợp nhất.

Vui lòng xem xét bài đăng này tôi đã viết một lúc trước: nó cho thấy sau khi thanh trừng nhiều hàng từ một bảng lớn, tệp dữ liệu bị phân mảnh (nghĩa là nó rất lớn trong hệ thống tệp - đó là vấn đề được biết các tệp này không bao giờ giảm kích thước). Tuy nhiên, các chỉ mục không bị phân mảnh khi kết thúc xóa: điều này là do InnoDB hợp nhất các trang khi chúng trở nên trống rỗng (er).

Các OPTIMIZElệnh thực sự không áp dụng trên InnoDB. Những gì nó làm là xây dựng lại bảng (chính xác như một ALTER). Xem cái này:

mysql [localhost] {msandbox} (test) > create table t(id int) engine=innodb;

mysql [localhost] {msandbox} (test) > optimize table t;
+--------+----------+----------+-------------------------------------------------------------------+
| Table  | Op       | Msg_type | Msg_text                                                          |
+--------+----------+----------+-------------------------------------------------------------------+
| test.t | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| test.t | optimize | status   | OK                                                                |
+--------+----------+----------+-------------------------------------------------------------------+

Đối với DATA_FREE: Tôi đề nghị bạn chỉ cần bỏ qua biến này. Thành thật mà nói, tôi đã làm việc với các bảng InnoDB trong 10nhiều năm và chưa bao giờ thấy giá trị này rất phù hợp với bất cứ điều gì.

Và bây giờ là lúc để thảo luận thực sự: chính xác thì bạn đang cố gắng đạt được điều gì? Trừ khi cơ sở dữ liệu của bạn hoàn toàn cũ, sẽ luôn có một số phân mảnh. Đó là điều tự nhiên đối với quá trình thêm, xóa và cập nhật các hàng trong bảng của bạn.

Phân mảnh không phải là xấu xa: không gian trống có thể được thu hồi bởi dữ liệu mới. Nếu bàn của bạn không lớn lắm, thì hãy quên đi toàn bộ. Đối với các bảng rất lớn, bạn có thể đạt được một số dung lượng đĩa bằng cách tối ưu hóa bảng. Nhưng hãy tự hỏi: làm thế nào sớm để bảng đạt được sự phân mảnh? Một tiếng? Một ngày? Một tuần? IMHO trong tất cả các trường hợp này, việc tối ưu hóa bảng là vô nghĩa.

Tuy nhiên, nếu một bảng lớn được thanh lọc dữ liệu ồ ạt, dự kiến ​​sẽ không quay trở lại, tất cả là để tối ưu hóa nó. Giả sử bạn nhận ra rằng bạn có một số dữ liệu dư thừa bao gồm khoảng 30% kích thước bảng của bạn. Chắc chắn, sẽ rất tuyệt nếu có không gian đĩa đó trở lại.

Điểm mấu chốt: chỉ xem xét các vấn đề này với các bảng rất lớn; Chỉ khi bạn có vấn đề với không gian đĩa.


Tôi đồng ý rằng data_free không hữu ích. Nó chỉ tính không gian trong "phạm vi miễn phí" cho không gian bảng là một số liệu khủng khiếp để tính toán phân mảnh. Tôi nghĩ rằng nếu bạn không sử dụng innodb_file_per_tablenó cũng sẽ hiển thị cùng một giá trị cho mỗi bảng trong không gian bảng được chia sẻ.
jeremycole
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.