Quantcast
Channel: 日々の覚書
Viewing all articles
Browse latest Browse all 581

インデックス vs InnoDBログ書き込みのサイズ観測

$
0
0

TL;DR

  • セカンダリーキーは意外とログ書き込みに響く。無駄なやつをなるべく消したりマージできたりするといいかも。

  • ナチュラルキーを使うのは書き込み面では誤差か。

    • 読み取りで差が出るといいなと思うけれど今日はやらない。
tablesizesize_vs_t1lsnlsn_vs_t1comment
t113,631,4881.0031,977,6821.00auto_increment PK + 0 key
t217,825,7921.3135,158,2931.10auto_increment PK + 1 key
t319,922,9441.4638,051,5391.19auto_increment PK + 2 key
t415,728,6401.1533,413,6341.04natural PK + 0 key
t519,922,9441.4637,070,7121.16natural PK + 1 key



MySQL 8.0.23を用意。


$ bin/mysqld --no-defaults --initialize-insecure --datadir=/tmp/data --lower_case_table_names=1 --log-error-verbosity=3

$ bin/mysqld --no-defaults --datadir=/tmp/data --lower_case_table_names=1 --log-error-verbosity=3 --daemonize
mysqld will log errors to /tmp/data/host.err
mysqld is running as pid 14865

テスト用のテーブルその1。AUTO_INCREMENTがPRIMARY KEYで他のインデックスなし。

mysql> CREATE TABLE d1.t1 (
-> num BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
-> user_id INT UNSIGNED NOT NULL,
-> something_id INT UNSIGNED NOT NULL,
-> something_count INT UNSIGNED NOT NULL,
-> updated DATETIME DEFAULT CURRENT_TIMESTAMP,
-> PRIMARY KEY(num)
-> );
Query OK, 0 rows affected (0.03 sec)

データロード後にチェンジバッファのマージでLSNが進むのが嫌なのでチェンジバッファはOFFに。

mysql> SET GLOBAL innodb_change_buffering = none;
Query OK, 0 rows affected (0.00 sec)

i_s.innodb_metricslog_lsn_currentが有効になってなかったので有効化。

mysql> SELECT name, count, status FROM information_schema.innodb_metrics WHERE name = 'log_lsn_current';
+-----------------+-------+----------+
| name | count | status |
+-----------------+-------+----------+
| log_lsn_current | 0 | disabled |
+-----------------+-------+----------+
1 row in set (0.00 sec)

mysql> SET GLOBAL innodb_monitor_enable = 'log_lsn_current';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT name, count, status FROM information_schema.innodb_metrics WHERE name = 'log_lsn_current';
+-----------------+----------+---------+
| name | count | status |
+-----------------+----------+---------+
| log_lsn_current | 18040637 | enabled |
+-----------------+----------+---------+
1 row in set (0.00 sec)

で、データをロード。

$ perl -MDBI -E 'my $conn= DBI->connect("dbi:mysql:d1;mysql_socket=/tmp/mysql.sock", "root", ""); for (my $something_id= 1; $something_id <= 100; $something_id++) { for (my $user_id= 1; $user_id <= 1000; $user_id++) { $conn->do("INSERT INTO t1 VALUES (NULL, ?, ?, 1, NOW())", undef, $user_id, $something_id) } }'

$ bin/mysql -e "SELECT name, count, status FROM information_schema.innodb_metrics WHERE name = 'log_lsn_current'"
+-----------------+----------+---------+
| name | count | status |
+-----------------+----------+---------+
| log_lsn_current | 50018319 | enabled |
+-----------------+----------+---------+

進んだLSNは 31,977,682。次。

mysql> CREATE TABLE d1.t2 (
-> num BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
-> user_id INT UNSIGNED NOT NULL,
-> something_id INT UNSIGNED NOT NULL,
-> something_count INT UNSIGNED NOT NULL,
-> updated DATETIME DEFAULT CURRENT_TIMESTAMP,
-> PRIMARY KEY(num),
-> KEY idx_userid (user_id)
-> );
Query OK, 0 rows affected (0.03 sec)

mysql> SELECT name, count, status FROM information_schema.innodb_metrics WHERE name = 'log_lsn_current';
+-----------------+----------+---------+
| name | count | status |
+-----------------+----------+---------+
| log_lsn_current | 50037236 | enabled |
+-----------------+----------+---------+
1 row in set (0.00 sec)

セカンダリーキーを1個増やしたバージョン。

$ perl -MDBI -E 'my $conn= DBI->connect("dbi:mysql:d1;mysql_socket=/tmp/mysql.sock", "root", ""); for (my $something_id= 1; $something_id <= 100; $something_id++) { for (my $user_id= 1; $user_id <= 1000; $user_id++) { $conn->do("INSERT INTO t2 VALUES (NULL, ?, ?, 1, NOW())", undef, $user_id, $something_id) } }'

$ bin/mysql -e "SELECT name, count, status FROM information_schema.innodb_metrics WHERE name = 'log_lsn_current'"
+-----------------+----------+---------+
| name | count | status |
+-----------------+----------+---------+
| log_lsn_current | 85195529 | enabled |
+-----------------+----------+---------+

35,158,293次。

mysql> CREATE TABLE d1.t3 (
-> num BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
-> user_id INT UNSIGNED NOT NULL,
-> something_id INT UNSIGNED NOT NULL,
-> something_count INT UNSIGNED NOT NULL,
-> updated DATETIME DEFAULT CURRENT_TIMESTAMP,
-> PRIMARY KEY(num),
-> KEY idx_userid (user_id),
-> KEY idx_updated (updated)
-> );
Query OK, 0 rows affected (0.04 sec)

mysql> SELECT name, count, status FROM information_schema.innodb_metrics WHERE name = 'log_lsn_current';
+-----------------+----------+---------+
| name | count | status |
+-----------------+----------+---------+
| log_lsn_current | 85218863 | enabled |
+-----------------+----------+---------+
1 row in set (0.00 sec)

更に追加でもう一つセカンダリーキー。

$ perl -MDBI -E 'my $conn= DBI->connect("dbi:mysql:d1;mysql_socket=/tmp/mysql.sock", "root", ""); for (my $something_id= 1; $something_id <= 100; $something_id++) { for (my $user_id= 1; $user_id <= 1000; $user_id++) { $conn->do("INSERT INTO t3 VALUES (NULL, ?, ?, 1, NOW())", undef, $user_id, $something_id) } }'

$ bin/mysql -e "SELECT name, count, status FROM information_schema.innodb_metrics WHERE name = 'log_lsn_current'"
+-----------------+-----------+---------+
| name | count | status |
+-----------------+-----------+---------+
| log_lsn_current | 123270402 | enabled |
+-----------------+-----------+---------+

38,051,539。少なくともファイルサイズほど大きくは増えない。

$ ll d1
total 50188
-rw-r----- 1 yoku0825 yoku0825 13631488 Feb 8 00:33 t1.ibd
-rw-r----- 1 yoku0825 yoku0825 17825792 Feb 8 00:39 t2.ibd
-rw-r----- 1 yoku0825 yoku0825 19922944 Feb 8 00:44 t3.ibd

4つめ。 (user_id, something_id)のナチュラルキー風。カラムの数を変えないために numは自分で詰める。 $user_idのループを内側にしてあるのでPRIMARY KEYのランダムインサート状態になる。
PKが user_idの検索に使えるので実質 t2プラスアルファ状態。

mysql> CREATE TABLE d1.t4 (
-> num BIGINT UNSIGNED NOT NULL,
-> user_id INT UNSIGNED NOT NULL,
-> something_id INT UNSIGNED NOT NULL,
-> something_count INT UNSIGNED NOT NULL,
-> updated DATETIME DEFAULT CURRENT_TIMESTAMP,
-> PRIMARY KEY(user_id, something_id)
-> );
Query OK, 0 rows affected (0.05 sec)

mysql> SELECT name, count, status FROM information_schema.innodb_metrics WHERE name = 'log_lsn_current';
+-----------------+-----------+---------+
| name | count | status |
+-----------------+-----------+---------+
| log_lsn_current | 123287410 | enabled |
+-----------------+-----------+---------+
1 row in set (0.00 sec)

$ perl -MDBI -E 'my $conn= DBI->connect("dbi:mysql:d1;mysql_socket=/tmp/mysql.sock", "root", ""); my $n= 1; for (my $something_id= 1; $something_id <= 100; $something_id++) { for (my $user_id= 1; $user_id <= 1000; $user_id++) { $conn->do("INSERT INTO t4 VALUES (?, ?, ?, 1, NOW())", undef, $n++, $user_id, $something_id) } }'

$ bin/mysql -e "SELECT name, count, status FROM information_schema.innodb_metrics WHERE name = 'log_lsn_current'"
+-----------------+-----------+---------+
| name | count | status |
+-----------------+-----------+---------+
| log_lsn_current | 156701044 | enabled |
+-----------------+-----------+---------+

33,413,634。セカンダリーキーを足してラスト。

mysql> CREATE TABLE d1.t5 (
-> num BIGINT UNSIGNED NOT NULL,
-> user_id INT UNSIGNED NOT NULL,
-> something_id INT UNSIGNED NOT NULL,
-> something_count INT UNSIGNED NOT NULL,
-> updated DATETIME DEFAULT CURRENT_TIMESTAMP,
-> PRIMARY KEY(user_id, something_id),
-> KEY idx_updated(updated)
-> );
Query OK, 0 rows affected (0.03 sec)

mysql> SELECT name, count, status FROM information_schema.innodb_metrics WHERE name = 'log_lsn_current';
+-----------------+-----------+---------+
| name | count | status |
+-----------------+-----------+---------+
| log_lsn_current | 156720509 | enabled |
+-----------------+-----------+---------+
1 row in set (0.00 sec)

$ bin/mysql -e "SELECT name, count, status FROM information_schema.innodb_metrics WHERE name = 'log_lsn_current'"
+-----------------+-----------+---------+
| name | count | status |
+-----------------+-----------+---------+
| log_lsn_current | 193791221 | enabled |
+-----------------+-----------+---------+

37,070,712。実質 t3相当で似たようなLSN。

で、冒頭の表再掲。

tablesizesize_vs_t1lsnlsn_vs_t1comment
t113,631,4881.0031,977,6821.00auto_increment PK + 0 key
t217,825,7921.3135,158,2931.10auto_increment PK + 1 key
t319,922,9441.4638,051,5391.19auto_increment PK + 2 key
t415,728,6401.1533,413,6341.04natural PK + 0 key
t519,922,9441.4637,070,7121.16natural PK + 1 key

Viewing all articles
Browse latest Browse all 581

Trending Articles