Эти два оператора имеют полностью другую производительность:
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);
Я думаю, что разница заключается в обработке нулевых значений (независимо от оператора NOT NULL в вашем случае). Может быть, эти разделы руководства могут помочь?
http://dev.mysql.com/doc/refman/5.1/en/comparison-operators.html http://dev.mysql.com/doc/refman/ 5.1 / ru / logic-operators.html # operator_not
MySQL не может использовать индекс для WHERE! CreateIndexed
, потому что ему необходимо вычислить NOT createIndexed
для каждой строки при сканировании таблицы.
Логически эти операции одинаковы, но оптимизатор MySQL
не настолько умен, чтобы увидеть createIndexed = 0
в НЕ createIndexed
.
FALSE
в MySQL
является просто синонимом для 0
, а TRUE
является синонимом для 1
.
Это условие неверно:
SELECT 2 = TRUE
--
0
, поэтому первый запрос представляет собой просто чистое сравнение индекса ref
с 0
, о котором MySQL
знает, в то время как второй содержит более сложную логику, которую MySQL
не может представить как выражение с возможностью саргетинга.
В MySQL ключевое слово FALSE не является логическим элементом данные: это целочисленная константа, равная нулю . Напротив, ! ( также известный как NOT ) - это логический оператор, который:
принимает значение 1, если операнд равен 0, до 0, если операнд не равен нулю, и NOT возвращает 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)
Но это не идентичные операции.