Is there a formula to estimate index size in InnoDB?

浪子不回头ぞ 提交于 2019-12-05 07:30:31

问题


How is it possible to calculate index size for specific column types in InnoDB i.e.:

  • VARCHAR
  • CHAR
  • TIMESTAMP
  • SMALLINT

I've found a formula for MyISAM (http://dev.mysql.com/doc/refman/5.7/en/key-space.html): (key_length+4)/0.67

Does this work for InnoDB as well?

I'm trying to estimate the size of a database I'm designing for sizing purposes.


回答1:


In InnoDB, the PRIMARY KEY is embedded with the data, so you can think of it as taking no space.

For a secondary key... Take the MyISAM formula, but include the columns of both the secondary key and the PRIMARY KEY. Then multiply by 3. (There is a lot of overhead.) Still, the answer can be off by a factor of 2 in either direction.

Note that if you have a lot of secondary keys, the size of the PK makes a big difference in the overall space for the table+indexes.

Example

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.)

Output:

+-------------+-------------------+-----------+-----------+-------+-----------+
| Approx Rows | Type              | Bytes     | Bytes/row | Pages | Rows/page |
+-------------+-------------------+-----------+-----------+-------+-----------+
|     2637973 | Data & PK         | 179077120 |        68 | 10930 |       241 |
|     2637973 | Secondary Indexes | 232341504 |        88 | 14181 |       186 |
+-------------+-------------------+-----------+-----------+-------+-----------+

The table has two indexes:

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")

Just to prove another point, I tried OPTIMIZE TABLE. The stats after there were essentially the same:

+-------------+-------------------+-----------+-----------+-------+-----------+
| Approx Rows | Type              | Bytes     | Bytes/row | Pages | Rows/page |
+-------------+-------------------+-----------+-----------+-------+-----------+
|     2685828 | Data & PK         | 179077120 |        67 | 10930 |       246 |
|     2685828 | Secondary Indexes | 232341504 |        87 | 14181 |       189 |
+-------------+-------------------+-----------+-----------+-------+-----------+



回答2:


One secondary index record is indexed fields + primary key. Sum up field sizes, multiply by number of records, add some overhead and that would be index size.



来源:https://stackoverflow.com/questions/38248452/is-there-a-formula-to-estimate-index-size-in-innodb

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!