Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Độ dài hàng trung bình cao hơn có thể

  • avg_row_lengthdata_length / rows .

data_length về cơ bản là tổng kích thước của bảng trên đĩa . Một bảng InnoDB không chỉ là một danh sách các hàng. Vì vậy, có thêm chi phí.

  • Vì hàng InnoDB nhiều hơn dữ liệu.

Tương tự như trên, mỗi hàng đi kèm với một số chi phí. Vì vậy, điều đó sẽ thêm vào kích thước của một hàng. Một bảng InnoDB cũng không chỉ là một danh sách dữ liệu được nhồi nhét vào nhau. Nó cần thêm một chút không gian trống để hoạt động hiệu quả.

  • Vì nội dung được lưu trữ trên đĩa theo khối và những khối đó không phải lúc nào cũng đầy.

Đĩa thường lưu trữ mọi thứ trong các khối 4K, 8K hoặc 16K . Đôi khi mọi thứ không khớp hoàn toàn trong các khối đó, vì vậy bạn có thể nhận được một số trống không gian .

Như chúng ta sẽ thấy bên dưới, MySQL sẽ phân bổ bảng theo khối. Và nó sẽ phân bổ nhiều hơn mức cần thiết để tránh phải tăng bảng (có thể chậm và dẫn đến phân mảnh đĩa điều này làm cho mọi thứ thậm chí còn chậm hơn).

Để minh họa điều này, hãy bắt đầu với một bảng trống.

mysql> create table foo ( id smallint(5) unsigned NOT NULL );
mysql> select data_length, table_rows, avg_row_length from information_schema.tables where table_name = 'foo';
+-------------+------------+----------------+
| data_length | table_rows | avg_row_length |
+-------------+------------+----------------+
|       16384 |          0 |              0 |
+-------------+------------+----------------+

Nó sử dụng 16K, hoặc bốn khối 4K, để lưu trữ không có gì. Bảng trống không cần không gian này, nhưng MySQL đã phân bổ nó dựa trên giả định rằng bạn sẽ đặt một loạt dữ liệu vào đó. Điều này tránh phải thực hiện phân bổ lại tốn kém trên mỗi phụ trang.

Bây giờ, hãy thêm một hàng.

mysql> insert into foo (id) VALUES (1);
mysql> select data_length, table_rows, avg_row_length from information_schema.tables where table_name = 'foo';
+-------------+------------+----------------+
| data_length | table_rows | avg_row_length |
+-------------+------------+----------------+
|       16384 |          1 |          16384 |
+-------------+------------+----------------+

Chiếc bàn không lớn hơn chút nào, có tất cả không gian chưa sử dụng trong 4 khối mà nó có. Có một hàng có nghĩa là avg_row_length là 16K. Rõ ràng là vô lý. Hãy thêm một hàng khác.

mysql> insert into foo (id) VALUES (1);
mysql> select data_length, table_rows, avg_row_length from information_schema.tables where table_name = 'foo';
+-------------+------------+----------------+
| data_length | table_rows | avg_row_length |
+-------------+------------+----------------+
|       16384 |          2 |           8192 |
+-------------+------------+----------------+

Điều tương tự. 16K được phân bổ cho bảng, 2 hàng sử dụng không gian đó. Một kết quả vô lý là 8K mỗi hàng.

Khi tôi chèn ngày càng nhiều hàng, kích thước bảng vẫn như cũ, sử dụng ngày càng nhiều không gian được phân bổ và avg_row_length đến gần hơn với thực tế.

mysql> select data_length, table_rows, avg_row_length from information_schema.tables where table_name = 'foo';                                                                     
+-------------+------------+----------------+
| data_length | table_rows | avg_row_length |
+-------------+------------+----------------+
|       16384 |       2047 |              8 |
+-------------+------------+----------------+

Tại đây, chúng ta cũng bắt đầu thấy table_rows trở nên không chính xác. Tôi chắc chắn đã chèn 2048 hàng.

Bây giờ khi tôi chèn thêm một số ...

mysql> select data_length, table_rows, avg_row_length from information_schema.tables where table_name = 'foo';
+-------------+------------+----------------+
| data_length | table_rows | avg_row_length |
+-------------+------------+----------------+
|       98304 |       2560 |             38 |
+-------------+------------+----------------+

(Tôi đã chèn 512 hàng và table_rows đã quay trở lại thực tế vì lý do nào đó)

MySQL quyết định bảng cần thêm dung lượng, vì vậy nó đã được thay đổi kích thước và chiếm thêm nhiều dung lượng đĩa hơn. avg_row_length vừa mới nhảy trở lại.

Nó chiếm nhiều không gian hơn nó cần cho 512 hàng đó, bây giờ là 96K hoặc 24 khối 4K, với giả định rằng nó sẽ cần nó sau này. Điều này giảm thiểu số lần tái phân bổ tiềm năng chậm mà nó cần phải thực hiện và giảm thiểu phân mảnh ổ đĩa.

Điều này không có nghĩa là tất cả không gian đó đã được lấp đầy . Nó chỉ có nghĩa là MySQL nghĩ rằng nó đã đầy đủ để cần thêm dung lượng để chạy hiệu quả. Nếu bạn muốn biết lý do tại sao lại như vậy, hãy xem cách một bảng băm hoạt động. Tôi không biết InnoDB có sử dụng bảng băm hay không nhưng nguyên tắc được áp dụng:một số cấu trúc dữ liệu hoạt động tốt nhất khi có một số không gian trống.

Đĩa được sử dụng bởi một bảng có liên quan trực tiếp đến số hàng và loại cột trong bảng, nhưng công thức chính xác rất khó tìm ra và sẽ thay đổi từ phiên bản này sang phiên bản khác của MySQL. Cách tốt nhất của bạn là thực hiện một số thử nghiệm thực nghiệm và tự từ chức rằng bạn sẽ không bao giờ nhận được con số chính xác.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kết nối với MySQL bằng SSH Tunneling trong node-mysql

  2. Làm thế nào để tìm email có nhiều hơn 2 dấu chấm bằng cách sử dụng chức năng REGEXP MySQL?

  3. SQL:Ở đâu giữa hai ngày không có năm?

  4. MySQLNonTransientConnectionException:Không thể tạo kết nối với máy chủ cơ sở dữ liệu

  5. Trong Rails Migration (MySQL), bạn có thể chỉ định vị trí của một cột mới không?