8月
10
真偽値型(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
no comment untill now