MySQL 中 !col 和 col=false 有什么区别?
两种语句的性能完全不同:
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);
The two statements have totally different performance:
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 |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
Column definition and related index for aiding analysis:
createIndexed tinyint(1) NOT NULL DEFAULT 0,
create index i_jobs_createIndexed on jobs(createIndexed);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
从逻辑上讲,这些操作是相同的,但是MySQL的优化器并没有那么聪明,无法在
NOT createIndexed
中看到createIndexed = 0
。MySQL
中的FALSE
只是0
的同义词,TRUE
是1
的同义词>。此条件为 false:
,因此第一个查询只是与
MySQL
识别的0
的纯索引ref
比较,而第二个查询包含 MySQL 无法表示为可控制表达式的更复杂的逻辑。Logically, these operations are the same, but
MySQL
's optimizer is just not so smart to seecreateIndexed = 0
inNOT createIndexed
.FALSE
inMySQL
is just a synonym for0
andTRUE
is a synonym for1
.This condition is false:
, so the first query is just a pure index
ref
comparison to0
whichMySQL
is aware of, while the second one contains more complex logic thatMySQL
cannot represent as a sargable expression.MySQL 无法将索引用于
WHERE !createIndexed
,因为它需要通过表扫描来评估每一行的NOT createIndexed
。MySQL cannot use the index for
WHERE !createIndexed
, because it needs to evaluateNOT createIndexed
for each row, with a table scan.我认为区别在于对空值的处理 - (无论您的情况中的 NOT NULL 语句如何)。也许这些手册部分可以提供帮助?
http://dev.mysql.com/doc/refman/ 5.1/en/comparison-operators.html
http://dev.mysql.com/doc/ refman/5.1/en/tical-operators.html#operator_not
I think the difference lies in the handling of null values - (regardless of the NOT NULL statement in your case). Maybe these manual sections can help?
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
在 MySQL 中,FALSE 关键字不是布尔数据:它是 等于零的整数常量。相反, ! (aka NOT) 是一个逻辑运算符:
我认为没有太大的实际差异:
但它们不是相同的操作。
In MySQL, the FALSE keyword is not a boolean piece of data: it's an integer constant that equals zero. On the contrary, ! (aka NOT) is a logical operator that:
I suppose that there's not much practical difference:
Yet they're not identical operations.