gpt4 book ai didi

MySQL:为什么 'FOO' IS NULL 没有被优化掉?

转载 作者:可可西里 更新时间:2023-11-01 06:50:04 26 4
gpt4 key购买 nike

MySQL 5.5.28。我有两个表 PersonMessage ,后者有前者的外键。每个表都有 id 作为主键列,Person 表还有一列 personId,它是(唯一)索引的。

下面的查询应该利用 personId 键索引,但是 MySQL 出于某种原因需要扫描整个 Message 表:

mysql> EXPLAIN SELECT `m`.*    -> FROM    ->   `Message` AS `m`    -> LEFT JOIN    ->   `Person` AS `p` ON (`m`.`person` = `p`.`id`)    -> WHERE    ->   'M002649397' IS NULL OR    ->   `p`.`personId` = 'M002649397';+----+-------------+-------+--------+---------------+---------+---------+----------------+--------+-------------+| id | select_type | table | type   | possible_keys | key     | key_len | ref            | rows   | Extra       |+----+-------------+-------+--------+---------------+---------+---------+----------------+--------+-------------+|  1 | SIMPLE      | m     | ALL    | NULL          | NULL    | NULL    | NULL           | 273220 |             ||  1 | SIMPLE      | p     | eq_ref | PRIMARY       | PRIMARY | 8       | pcom.m.person  |      1 | Using where |+----+-------------+-------+--------+---------------+---------+---------+----------------+--------+-------------+2 rows in set (0.00 sec)

但是当我注释掉 'M002649397' IS NULL OR 子句(对结果没有影响)时,查询突然变得更加高效:

mysql> EXPLAIN SELECT `m`.*    -> FROM    ->   `Message` AS `m`    -> LEFT JOIN    ->   `Person` AS `p` ON (`m`.`person` = `p`.`id`)    -> WHERE    -> --  'M002649397' IS NULL OR    ->   `p`.`personId` = 'M002649397';+----+-------------+-------+-------+--------------------+--------------------+---------+-------+------+-------------+| id | select_type | table | type  | possible_keys      | key                | key_len | ref   | rows | Extra       |+----+-------------+-------+-------+--------------------+--------------------+---------+-------+------+-------------+|  1 | SIMPLE      | p     | const | PRIMARY,personId   | personId           | 767     | const |    1 | Using index ||  1 | SIMPLE      | m     | ref   | FK9C2397E7A0F6ED11 | FK9C2397E7A0F6ED11 | 9       | const |    3 | Using where |+----+-------------+-------+-------+--------------------+--------------------+---------+-------+------+-------------+2 rows in set (0.01 sec)

我的问题是:为什么 MySQL 不够聪明,无法意识到 'M002649397' IS NULL 始终为 false,将其优化掉,从而避免不必要地扫描巨大表中的每一行?

换句话说,MySQL 优化器是否不知道 'M002649397' IS NULL 始终为 false,或者它是否在构建查询计划时未能将优化应用于查询?

最佳答案

实际上,更有趣的是文档说 MySQL 足够智能来执行此操作(参见 here)。

这似乎在标题“8.2.1.2. 消除“死”代码”下。

我想原因是开发人员在编写代码时没有考虑诸如“is not null”之类的表达式。该文档给出了许多基于常量传播的示例(x1 = 2 and x2 = x1 变为 x1 = 2 and x2 = 2)。 is null 可能确实出现在这种情况下。

关于MySQL:为什么 'FOO' IS NULL 没有被优化掉?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16848190/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com