2016-07-07 3 views
1

MyISAM(http://dev.mysql.com/doc/refman/5.7/en/key-space.html):(key_length + 4)/0.67InnoDBのインデックスサイズを見積もる式はありますか?私は式を見つけた</p> <ul> <li>VARCHAR</li> <li>CHAR</li> <li>TIMESTAMP</li> <li>SMALLINT</li> </ul> <p>:どのようにそれはInnoDBのIEで特定の列の型のインデックスサイズを計算することが可能である

InnoDBでも使えますか?

私はサイジング目的のために設計しているデータベースのサイズを推定しようとしています。

答えて

1

1つのセカンダリインデックスレコードは、インデックス付きフィールド+プライマリキーです。フィールドサイズを合計し、レコード数を掛け、オーバーヘッドを追加します。これはインデックスサイズになります。

3

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

ありがとう。これはドキュメントのどこかにありますか?私はどこでもそれを見つけることができません。 – L4zl0w

+0

実際にはありません。 '* 3'は何十もの表を調べて経験的に得られたものです。 Jeremy Coleのブログの中には、データがどのように格納されているかについての詳細な情報が含まれています。細かいところを見ると、私の単純な「* 3」よりも良い答えが得られないかもしれません - 多くのことが数式に影響します。 –

+0

1つの極端な場合、1つのセカンダリインデックスを持つ1行テーブルは、データ用に16KBのブロックを割り当て、インデックス用にもう1つのブロックを割り当てます。これは '* 3'以上のものです。インデックスは断片化することも、新たに断片化を解消することもできます。これは、おそらくもっと多かれ少なかれ "* 1.5"の差を生み出すことができます。 'ROW_FORMAT'には多少の影響があります。私はどれくらいのことを知らない。 –

関連する問題

 関連する問題