2010-03-25 17 views
9

Las dos declaraciones tienen totalmente diferente rendimiento:¿Cuál es la diferencia entre! Col y col = false en MySQL?

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 | 
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+ 

Definición de columna y el índice correspondiente para el análisis de ayudar:

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

Respuesta

3

MySQL no puede usar el índice para WHERE !createIndexed, ya que tiene que evaluar NOT createIndexed para cada fila , con un escaneo de tabla.

5

Lógicamente, estas operaciones son las mismas, pero el optimizador de MySQL no es tan inteligente como para ver createIndexed = 0 en NOT createIndexed.

FALSE en MySQL es simplemente un sinónimo de 0 y TRUE es sinónimo de 1.

Esta condición es falsa:

SELECT 2 = TRUE 

-- 
0 

, por lo que la primera consulta es sólo una pura comparación índice ref-0 cuales MySQL es consciente de, mientras que el segundo contiene una lógica más compleja que MySQL no se puede representar como una expresión sargable

+0

+1 para la explicación clara y técnica. –

+0

+1 por mencionar el optimizador –

+0

El optimizador de MySQL es tan débil que me sorprende – Mask

0

En MySQL, la palabra clave no es FALSO una pieza booleano de los datos: se trata de un integer constant that equals zero. De lo contrario, ! (aka NOT) es un operador lógico que:

evalúa como 1 si el operando es 0, a 0 si el operando no es cero, y NO NULL devuelve NULL.

supongo que no hay mucha diferencia práctica:

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) 

Sin embargo, ellos no son operaciones idénticas.

Cuestiones relacionadas