Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Panjang baris rata-rata lebih tinggi dari yang mungkin

  • Karena avg_row_length adalah data_length / rows .

data_length pada dasarnya adalah ukuran total tabel pada disk . Tabel InnoDB lebih dari sekadar daftar baris. Jadi ada biaya tambahan.

  • Karena baris InnoDB lebih dari sekadar data.

Mirip dengan di atas, setiap baris dilengkapi dengan beberapa overhead. Jadi itu akan menambah ukuran baris. Tabel InnoDB juga bukan hanya daftar data yang dijejalkan bersama. Dibutuhkan sedikit ruang kosong ekstra untuk bekerja secara efisien.

  • Karena barang disimpan di disk dalam blok dan blok tersebut tidak selalu penuh.

Disk menyimpan sesuatu biasanya dalam 4K, 8K, atau 16K blok . Terkadang ada yang tidak pas di blok tersebut, jadi Anda bisa mendapatkan beberapa kosong ruang .

Seperti yang akan kita lihat di bawah, MySQL akan mengalokasikan tabel dalam blok. Dan itu akan mengalokasikan lebih banyak daripada yang dibutuhkan untuk menghindari keharusan menumbuhkan tabel (yang bisa lambat dan mengarah ke fragmentasi disk yang membuat segalanya lebih lambat).

Untuk mengilustrasikannya, mari kita mulai dengan tabel kosong.

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 |
+-------------+------------+----------------+

Ini menggunakan 16K, atau empat blok 4K, untuk tidak menyimpan apa pun. Tabel kosong tidak membutuhkan ruang ini, tetapi MySQL mengalokasikannya dengan asumsi bahwa Anda akan meletakkan banyak data di dalamnya. Ini menghindari keharusan melakukan realokasi yang mahal pada setiap sisipan.

Sekarang mari kita tambahkan satu baris.

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 |
+-------------+------------+----------------+

Meja tidak bertambah besar, ada semua ruang yang tidak terpakai di dalam 4 blok yang dimilikinya. Ada satu baris yang berarti avg_row_length dari 16K. Jelas tidak masuk akal. Mari tambahkan baris lain.

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 |
+-------------+------------+----------------+

Hal yang sama. 16K dialokasikan untuk tabel, 2 baris menggunakan ruang itu. Hasil yang tidak masuk akal dari 8K per baris.

Saat saya memasukkan lebih banyak dan lebih banyak baris, ukuran tabel tetap sama, menggunakan lebih banyak dan lebih banyak ruang yang dialokasikan, dan avg_row_length semakin mendekati kenyataan.

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 |
+-------------+------------+----------------+

Di sini juga kita mulai melihat table_rows menjadi tidak akurat. Saya pasti memasukkan 2048 baris.

Sekarang ketika saya memasukkan beberapa lagi...

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 |
+-------------+------------+----------------+

(Saya memasukkan 512 baris, dan table_rows telah kembali ke kenyataan karena suatu alasan)

MySQL memutuskan tabel membutuhkan lebih banyak ruang, sehingga ukurannya diubah dan mengambil lebih banyak ruang disk. avg_row_length baru saja melompat lagi.

Itu mengambil lebih banyak ruang daripada yang dibutuhkan untuk 512 baris itu, sekarang menjadi 96K atau 24 blok 4K, dengan asumsi bahwa itu akan membutuhkannya nanti. Ini meminimalkan berapa banyak realokasi yang berpotensi lambat yang perlu dilakukan dan meminimalkan fragmentasi disk.

Ini tidak berarti bahwa semua ruang telah terisi . Itu hanya berarti MySQL berpikir itu cukup penuh untuk membutuhkan lebih banyak ruang untuk berjalan secara efisien. Jika Anda ingin mengetahui alasannya, lihat bagaimana tabel hash beroperasi. Saya tidak tahu apakah InnoDB menggunakan tabel hash, tetapi prinsipnya berlaku:beberapa struktur data beroperasi paling baik jika ada ruang kosong.

Disk yang digunakan oleh tabel berhubungan langsung dengan jumlah baris dan jenis kolom dalam tabel, tetapi rumus yang tepat sulit untuk diketahui dan akan berubah dari versi ke versi MySQL. Taruhan terbaik Anda adalah melakukan beberapa pengujian empiris dan mengundurkan diri bahwa Anda tidak akan pernah mendapatkan angka pasti.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL:Mengetik NULL ke 0

  2. HITUNG PERSENTASE DALAM SQL menurut grup

  3. Memeriksa konflik rentang tanggal di MySQL

  4. DI MANA vs MEMILIKI

  5. Menghubungkan ke mysql di 000webhost menggunakan C#