真偽値型(BIT(1) とか BOOLEAN(TINYINT のエイリアス)のこと)のカラムにインデックスを張っても、手抜きな SQL 文を書くとインデックスを使ってくれないようです。

mysql> CREATE TABLE booltest (
    bit1 BIT(1)           NOT NULL,
    tis  TINYINT          NOT NULL,
    tiu  TINYINT UNSIGNED NOT NULL,
    val  INT              NOT NULL,
    INDEX (bit1),
    INDEX (tis),
    INDEX (tiu)
);
(略)
(ランダムなデータをプログラム的につっこむ)
mysql> EXPLAIN SELECT * FROM BOOLTEST WHERE bit1;
+----+-------------+----------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table    | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra       |
+----+-------------+----------+------------+------+---------------+------+---------+------+--------+----------+-------------+
|  1 | SIMPLE      | booltest | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 998681 |    50.00 | Using where |
+----+-------------+----------+------------+------+---------------+------+---------+------+--------+----------+-------------+
mysql> EXPLAIN SELECT * FROM BOOLTEST WHERE bit1 = true;
+----+-------------+----------+------------+------+---------------+------+---------+-------+--------+----------+-------+
| id | select_type | table    | partitions | type | possible_keys | key  | key_len | ref   | rows   | filtered | Extra |
+----+-------------+----------+------------+------+---------------+------+---------+-------+--------+----------+-------+
|  1 | SIMPLE      | booltest | NULL       | ref  | bit1          | bit1 | 1       | const | 499340 |   100.00 | NULL  |
+----+-------------+----------+------------+------+---------------+------+---------+-------+--------+----------+-------+

bit1 = true と書かないとインデックスを使ってくれません。TINYINT 型にしてある tis, tiu でも同様です。普通のプログラミング言語なら bit1 が真偽値型なら bit1 と書いたのと bit1 = true と比較演算したのとは全く同じであるはずですが、SQL (MySQL) ではそういう挙動になってくれないようです。ちなみに EXPLAIN を外して実際にクエリしてみた場合、出てくる行は順番も含めて同じです。

まあ、プログラマが勝手に真偽値型だと思ってるだけであって、 TINYINT は数値型だし BIT(1) は値域が限定されている BINARY 型でしかないなので、MySQL はそこまで気を効かせてくれないのかもしれない…

使った環境:

  • Ubuntu 18.04 TLS
  • MySQL 5.7.27
Trackback

no comment untill now

Add your comment now