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で剰余算はインデックスが効かないようです。 どうすればいいのでしょう・・・?