2014年7月14日月曜日

TokuDBでパーティションが変に遅い件

とりあえずメモ。

mysql> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `num` int(10) unsigned NOT NULL,
  `val` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`num`)
) ENGINE=TokuDB DEFAULT CHARSET=utf8
1 row in set (0.01 sec)

mysql> SHOW CREATE TABLE t2\G
*************************** 1. row ***************************
       Table: t2
Create Table: CREATE TABLE `t2` (
  `num` int(10) unsigned NOT NULL,
  `val` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`num`)
) ENGINE=TokuDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY HASH (num)
PARTITIONS 10 */
1 row in set (0.00 sec)

mysql> SHOW CREATE TABLE t3\G
*************************** 1. row ***************************
       Table: t3
Create Table: CREATE TABLE `t3` (
  `num` int(10) unsigned NOT NULL,
  `val` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`num`)
) ENGINE=TokuDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (num)
(PARTITION p0 VALUES LESS THAN (100000) ENGINE = TokuDB,
 PARTITION p1 VALUES LESS THAN (200000) ENGINE = TokuDB,
 PARTITION p2 VALUES LESS THAN (300000) ENGINE = TokuDB,
 PARTITION p3 VALUES LESS THAN (400000) ENGINE = TokuDB,
 PARTITION p4 VALUES LESS THAN (500000) ENGINE = TokuDB,
 PARTITION p5 VALUES LESS THAN (600000) ENGINE = TokuDB,
 PARTITION p6 VALUES LESS THAN (700000) ENGINE = TokuDB,
 PARTITION p7 VALUES LESS THAN (800000) ENGINE = TokuDB,
 PARTITION p8 VALUES LESS THAN (900000) ENGINE = TokuDB,
 PARTITION p9 VALUES LESS THAN (1000000) ENGINE = TokuDB,
 PARTITION px VALUES LESS THAN MAXVALUE ENGINE = TokuDB) */
1 row in set (0.00 sec)

mysql> LOAD DATA INFILE '/tmp/md5' INTO TABLE t1;
Query OK, 1000000 rows affected (12.70 sec)
Records: 1000000  Deleted: 0  Skipped: 0  Warnings: 0

mysql> LOAD DATA INFILE '/tmp/md5' INTO TABLE t2;
Query OK, 1000000 rows affected (13.12 sec)
Records: 1000000  Deleted: 0  Skipped: 0  Warnings: 0

mysql> LOAD DATA INFILE '/tmp/md5' INTO TABLE t3;
Query OK, 1000000 rows affected (13.00 sec)
Records: 1000000  Deleted: 0  Skipped: 0  Warnings: 0

パーティショニングなし, HASHパーティショニング, RANGEパーティショニングの3つに同じデータを詰める。

mysql> SELECT COUNT(*) FROM t1;
+----------+
| COUNT(*) |
+----------+
|  1000000 |
+----------+
1 row in set (0.54 sec)

mysql> SELECT COUNT(*) FROM t2;
+----------+
| COUNT(*) |
+----------+
|  1000000 |
+----------+
1 row in set (3.39 sec)

mysql> SELECT COUNT(*) FROM t3;
+----------+
| COUNT(*) |
+----------+
|  1000000 |
+----------+
1 row in set (3.51 sec)

同じクエリーを4回投げて、一番遅いものを捨てて(キャッシュがあったまってないやつ)、3回の中央値で比較。
WHERE句なし。パーティション2つが異様に重い。

mysql> SELECT COUNT(*) FROM t1 WHERE num > 900000;
+----------+
| COUNT(*) |
+----------+
|   100000 |
+----------+
1 row in set (0.06 sec)

mysql> SELECT COUNT(*) FROM t2 WHERE num > 900000;
+----------+
| COUNT(*) |
+----------+
|   100000 |
+----------+
1 row in set (0.05 sec)

mysql> SELECT COUNT(*) FROM t3 WHERE num > 900000;
+----------+
| COUNT(*) |
+----------+
|   100000 |
+----------+
1 row in set (0.36 sec)

…あれ、パーティションの刈り込みが効くはずのt3がものすごく遅い。。

mysql> explain partitions SELECT COUNT(*) FROM t1 WHERE num > 900000;
+----+-------------+-------+------------+-------+---------------+---------+---------+------+--------+--------------------------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref  | rows   | Extra                    |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+--------+--------------------------+
|  1 | SIMPLE      | t1    | NULL       | range | PRIMARY       | PRIMARY | 4       | NULL | 114200 | Using where; Using index |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+--------+--------------------------+
1 row in set (0.02 sec)

mysql> explain partitions SELECT COUNT(*) FROM t2 WHERE num > 900000;
+----+-------------+-------+-------------------------------+-------+---------------+---------+---------+------+--------+--------------------------+
| id | select_type | table | partitions                    | type  | possible_keys | key     | key_len | ref  | rows   | Extra                    |
+----+-------------+-------+-------------------------------+-------+---------------+---------+---------+------+--------+--------------------------+
|  1 | SIMPLE      | t2    | p0,p1,p2,p3,p4,p5,p6,p7,p8,p9 | range | PRIMARY       | PRIMARY | 4       | NULL | 103200 | Using where; Using index |
+----+-------------+-------+-------------------------------+-------+---------------+---------+---------+------+--------+--------------------------+
1 row in set (0.00 sec)

mysql> explain partitions SELECT COUNT(*) FROM t3 WHERE num > 900000;
+----+-------------+-------+------------+-------+---------------+---------+---------+------+--------+--------------------------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref  | rows   | Extra                    |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+--------+--------------------------+
|  1 | SIMPLE      | t3    | p9,px      | index | PRIMARY       | PRIMARY | 4       | NULL | 100001 | Using where; Using index |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+--------+--------------------------+
1 row in set (0.00 sec)

ちゃんと刈り込めてはいるんだけどなーてか、t3のときだけインデックススキャンになってる。なんでだ。


【2014/07/15 11:55】
XtraDBでも調べた => TokuDBで変にパーティションが遅い件の比較用XtraDB


【2014/07/16 18:09】
バグらしい。中の人がMLにリプライくれた。=> https://groups.google.com/d/msg/tokudb-user/EjKSr_QuLYI/DSBH7PZ3v7AJ

0 件のコメント :

コメントを投稿