InnoDBでは、PRIMARY KEY
にデータが埋め込まれているため、空き領域がないと考えることができます。
セカンダリキーの場合... MyISAM式を使用しますが、の列には、のセカンダリキーとPRIMARY KEY
の両方の列を含めます。それから、3を掛けます(オーバーヘッドがたくさんあります)。答えはいずれの方向にも2分の1になります。
多くのセカンダリキーがある場合、PKのサイズはテーブル+インデックスの全体的なスペースに大きな違いがあることに注意してください。
例
SET @db = 'world', @tbl = 'cities';
SELECT n_rows AS 'Approx Rows',
'Data & PK' AS 'Type',
clustered_index_size * 16384 AS Bytes,
ROUND(clustered_index_size * 16384/n_rows) AS 'Bytes/row',
clustered_index_size AS Pages,
ROUND(n_rows/clustered_index_size) AS 'Rows/page'
FROM mysql.innodb_table_stats
WHERE database_name = @db
AND table_name = @tbl
UNION
SELECT n_rows,
'Secondary Indexes' AS 'BTrees',
sum_of_other_index_sizes * 16384 AS Bytes,
ROUND(sum_of_other_index_sizes * 16384/n_rows) AS 'Bytes/row',
sum_of_other_index_sizes AS Pages,
ROUND(n_rows/sum_of_other_index_sizes) AS 'Rows/page'
FROM mysql.innodb_table_stats
WHERE database_name = @db
AND table_name = @tbl
AND sum_of_other_index_sizes > 0
;
-- (Percona has a different way.)
出力:
+-------------+-------------------+-----------+-----------+-------+-----------+
| Approx Rows | Type | Bytes | Bytes/row | Pages | Rows/page |
+-------------+-------------------+-----------+-----------+-------+-----------+
| 2637973 | Data & PK | 179077120 | 68 | 10930 | 241 |
| 2637973 | Secondary Indexes | 232341504 | 88 | 14181 | 186 |
+-------------+-------------------+-----------+-----------+-------+-----------+
テーブルが2つのインデックスがあります
PRIMARY KEY(...) -- 14 bytes
INDEX(state, population)
INDEX(state, city)
state CHAR(2) CHARACTER SET ascii -- 2 bytes
population INT UNSIGNED -- 4 bytes
city -- AVG(LENGTH(city)) = 1+9.07 bytes
COUNT(*): 2,699,354 (the InnoDB estimate was not too far from this)
First index: 20 bytes * 2.7M rows = 54MB
Second index: 26.07 bytes * 2.7M rows = 70MB
Total: 124MB
Actual: 232MB
Ratio: 1.9x (note: I skipped the "/0.67")
ちょうど別のポイントを証明するために、私はOPTIMIZE TABLE
を試してみました。その後の統計は本質的に同じであった:
+-------------+-------------------+-----------+-----------+-------+-----------+
| Approx Rows | Type | Bytes | Bytes/row | Pages | Rows/page |
+-------------+-------------------+-----------+-----------+-------+-----------+
| 2685828 | Data & PK | 179077120 | 67 | 10930 | 246 |
| 2685828 | Secondary Indexes | 232341504 | 87 | 14181 | 189 |
+-------------+-------------------+-----------+-----------+-------+-----------+
ありがとう。これはドキュメントのどこかにありますか?私はどこでもそれを見つけることができません。 – L4zl0w
実際にはありません。 '* 3'は何十もの表を調べて経験的に得られたものです。 Jeremy Coleのブログの中には、データがどのように格納されているかについての詳細な情報が含まれています。細かいところを見ると、私の単純な「* 3」よりも良い答えが得られないかもしれません - 多くのことが数式に影響します。 –
1つの極端な場合、1つのセカンダリインデックスを持つ1行テーブルは、データ用に16KBのブロックを割り当て、インデックス用にもう1つのブロックを割り当てます。これは '* 3'以上のものです。インデックスは断片化することも、新たに断片化を解消することもできます。これは、おそらくもっと多かれ少なかれ "* 1.5"の差を生み出すことができます。 'ROW_FORMAT'には多少の影響があります。私はどれくらいのことを知らない。 –