MySQL 5.5.28。私には2つのテーブルがPerson
ありMessage
、後者には前者への外部キーがあります。各テーブルにid
は主キー列があり、Person
テーブルpersonId
には (一意に) インデックス付けされた列もあります。
以下のクエリはキー インデックスを利用する必要がありますが、MySQL では何らかの理由でテーブルpersonId
全体をスキャンする必要があります。Message
mysql> EXPLAIN SELECT `m`.* -> から -> `Message` AS `m` -> 左結合 -> `Person` AS `p` ON (`m`.`person` = `p`.`id`) ->どこで -> 'M002649397' は NULL または -> `p`.`personId` = 'M002649397'; +----+-------------+-------+--------+------------- --+---------+---------+----------------+--------+- ------------+ | | ID | select_type | テーブル | タイプ | 可能な_キー | キー | key_len | 参照 | 行 | 行 エクストラ | +----+-------------+-------+--------+------------- --+---------+---------+----------------+--------+- ------------+ | | 1 | シンプル | メートル | すべて | ヌル | ヌル | ヌル | ヌル | 273220 | | | | | 1 | シンプル | p | eq_ref | プライマリ | プライマリ | 8 | pcom.m.person | 1 | where | の使用 +----+-------------+-------+--------+------------- --+---------+---------+----------------+--------+- ------------+ 2 行セット (0.00 秒)
しかし、句をコメントアウトすると'M002649397' IS NULL OR
(結果には影響しません)、クエリが突然効率的になります。
mysql> EXPLAIN SELECT `m`.* -> から -> `Message` AS `m` -> 左結合 -> `Person` AS `p` ON (`m`.`person` = `p`.`id`) ->どこで -> -- 'M002649397' は NULL または -> `p`.`personId` = 'M002649397'; +----+-------------+-------+-------+-------------- ------+--------------------+---------+-------+---- --+-------------+ | | ID | select_type | テーブル | タイプ | 可能な_キー | キー | key_len | 参照 | 行 | 行 エクストラ | +----+-------------+-------+-------+-------------- ------+--------------------+---------+-------+---- --+-------------+ | | 1 | シンプル | p | 定数 | PRIMARY,personId | 個人ID | 767 | 定数 | 1 | インデックスの使用 | | | 1 | シンプル | メートル | 参照 | FK9C2397E7A0F6ED11 | FK9C2397E7A0F6ED11 | 9 | 定数 | 3 | where | の使用 +----+-------------+-------+-------+-------------- ------+--------------------+---------+-------+---- --+-------------+ 2行セット (0.01秒)
私の質問は、MySQL'M002649397' IS NULL
が常に false であることを認識し、それを最適化し、巨大なテーブルのすべての行を不必要にスキャンする必要をなくすことができないのはなぜですか?
言い換えれば、MySQL オプティマイザはそれ'M002649397' IS NULL
が常に false であることを認識していないのでしょうか? それとも、クエリ プランを作成するときにその最適化をクエリに適用できていないのでしょうか?