Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Gibt es eine Formel zur Schätzung der Indexgröße in InnoDB?

In InnoDB der PRIMARY KEY ist in die Daten eingebettet, sodass Sie sich vorstellen können, dass es keinen Platz einnimmt.

Für einen sekundären Schlüssel ... Nehmen Sie die MyISAM-Formel, aber schließen Sie die Spalten von beiden ein den Sekundärschlüssel und den PRIMARY KEY . Dann mit 3 multiplizieren. (Es gibt viel Overhead.) Trotzdem kann die Antwort um den Faktor 2 in beide Richtungen abweichen.

Beachten Sie, dass bei vielen Sekundärschlüsseln die Größe des PK einen großen Unterschied im Gesamtspeicherplatz für die Tabelle + Indizes ausmacht.

Beispiel

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

Ausgabe:

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

Die Tabelle hat zwei Indizes:

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

Nur um einen weiteren Punkt zu beweisen, habe ich OPTIMIZE TABLE ausprobiert . Die Statistiken danach waren im Wesentlichen die gleichen:

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