【问题标题】:What's the difference between !col and col=false in MySQL?MySQL 中的 !col 和 col=false 有什么区别?
【发布时间】:2011-01-31 19:29:18
【问题描述】:

这两个语句的性能完全不同:

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);

【问题讨论】:

    标签: sql mysql query-optimization


    【解决方案1】:

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

    如果操作数为 0,则计算为 1,以 如果操作数非零,则为 0,并且 NOT 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)
    

    但它们并不是完全相同的操作。

    【讨论】:

      【解决方案2】:

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

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

      此条件为假:

      SELECT  2 = TRUE
      
      --
      0
      

      ,所以第一个查询只是refMySQL 知道的0 的纯索引比较,而第二个查询包含更复杂的逻辑,MySQL 无法表示为可搜索表达式。

      【讨论】:

      • MySQL优化器弱到让我吃惊
      【解决方案3】:

      我认为区别在于空值的处理 - (无论您的情况是 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

      【讨论】:

      • NULL 值不会满足这两个查询。
      【解决方案4】:

      MySQL 不能使用WHERE !createIndexed 的索引,因为它需要通过表扫描来评估每一行的NOT createIndexed

      【讨论】:

        猜你喜欢
        • 2013-11-20
        • 2013-12-13
        • 2014-03-05
        • 2022-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-13
        相关资源
        最近更新 更多