MySQL中的!col和col = false有什么区别?

时间:2010-03-25 16:08:55

标签: sql mysql query-optimization

这两个陈述的表现完全不同:

mysql> explain select * from jobs  where createIndexed=false;
+----+-------------+-------+------+----------------------+----------------------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys        | key                  | key_len | ref   | rows | Extra |
+----+-------------+-------+------+----------------------+----------------------+---------+-------+------+-------+
|  1 | SIMPLE      | jobs  | ref  | i_jobs_createIndexed | i_jobs_createIndexed | 1       | const |    1 |       | 
+----+-------------+-------+------+----------------------+----------------------+---------+-------+------+-------+
1 row in set (0.01 sec)

mysql> explain select * from jobs  where !createIndexed;
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
|  1 | SIMPLE      | jobs  | ALL  | NULL          | NULL | NULL    | NULL | 17996 | Using where | 
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+

帮助分析的列定义和相关索引:

createIndexed tinyint(1) NOT NULL DEFAULT 0,
create index i_jobs_createIndexed on jobs(createIndexed);

4 个答案:

答案 0 :(得分:5)

从逻辑上讲,这些操作是相同的,但MySQL的优化程序在createIndexed = 0中看到NOT createIndexed并不是那么聪明。

FALSE中的

MySQL只是0的同义词,而TRUE1的同义词。

这种情况是错误的:

SELECT  2 = TRUE

--
0

,所以第一个查询只是ref0比较MySQL所知的纯索引MySQL,而第二个查询包含{{1}}无法识别的更复杂逻辑代表一种可以表达的表达方式。

答案 1 :(得分:3)

MySQL无法使用WHERE !createIndexed的索引,因为它需要使用表扫描为每行评估NOT createIndexed

答案 2 :(得分:0)

我认为不同之处在于处理空值 - (无论您的情况是否为NOT NULL语句)。也许这些手册部分可以提供帮助吗?

http://dev.mysql.com/doc/refman/5.1/en/comparison-operators.html http://dev.mysql.com/doc/refman/5.1/en/logical-operators.html#operator_not

答案 3 :(得分:0)

在MySQL中,FALSE关键字不是布尔数据:它是integer constant that equals zero。反之, ! (aka NOT)是一个逻辑运算符:

  

如果操作数为0,则求值为1   如果操作数非零,则为0,而不是   NULL返回NULL。

我认为没有太大的实际区别:

mysql> select 1=0, 0=0, 33=0, null=0, not 1, not 0, not 33, not null;
+-----+-----+------+--------+-------+-------+--------+----------+
| 1=0 | 0=0 | 33=0 | null=0 | not 1 | not 0 | not 33 | not null |
+-----+-----+------+--------+-------+-------+--------+----------+
|   0 |   1 |    0 |   NULL |     0 |     1 |      0 |     NULL |
+-----+-----+------+--------+-------+-------+--------+----------+
1 row in set (0.00 sec)

但他们的行动并不相同。