ポンコツエンジニアのごじゃっぺ開発日記。

いろいろポンコツだけど、気にするな。エンジニアの日々の開発などの記録を残していきます。 自動で収入を得られるサービスやシステムを作ることが目標!!

【検証】MySQLで剰余算のmodはインデックスが効くのか?

MySQLでこのカラムの数値が偶数のものだけ持ってきたい、そんなときはありませんか? (ほぼないかも・・・?あればコメント欄で教えて下さい!)

ただ、そのクエリを投げたときにインデックスが効くのか、というのが気になるところ。 ということで、今回は検証してみました!

環境

とあるuserテーブルを用意しました。

mysql> select count(*) from user;
+----------+
| count(*) |
+----------+
|     1000 |
+----------+
1 row in set (0.01 sec)

レコードは1000件入っています。

mysql> show index from user;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+-------------
| user  |          0 | PRIMARY  |            1 | id          | A         |          91 |     NULL | NULL   |      | BTREE      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+-------------
4 rows in set (0.01 sec)

よくあるテーブルのように、idのカラムがユニークインデックスとなっています。

このテーブルに対してクエリを投げてみたいと思います。

検証

まずは、通常のselect文です。

mysql> explain select * from user where id=200;
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | user  | NULL       | const | PRIMARY       | PRIMARY | 8       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

where句にidを指定するだけだと、ちゃんとインデックスが効いていることがわかります。

次は剰余算です。modを使ってみます。

mysql> explain select * from user where mod(id,3)=0;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | user  | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 1000 |   100.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

残念ながらインデックスが効かず、Using whereになってしまいました。。

mysql> explain select * from user where id%3=0;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | user  | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 1000 |   100.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

%を使った条件も同じ結果になりました。

結論

ということで、MySQLで剰余算はインデックスが効かないようです。 どうすればいいのでしょう・・・?

お問い合わせプライバシーポリシー制作物