2010-03-25 6 views
9

Les deux déclarations ont des performances totalement différentes:Quelle est la différence entre! Col et col = false dans 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 | 
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+ 

Colonne définition et index connexe pour l'analyse aidant:

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

Répondre

3

MySQL ne peut pas utiliser l'index pour WHERE !createIndexed, parce qu'il a besoin d'évaluer NOT createIndexed pour chaque ligne , avec un scan de table.

5

Logiquement, ces opérations sont les mêmes, mais l'optimiseur de MySQL n'est tout simplement pas si intelligent de voir createIndexed = 0 dans NOT createIndexed.

FALSE dans MySQL est un synonyme de 0 et TRUE est synonyme de 1.

Cette condition est fausse:

SELECT 2 = TRUE 

-- 
0 

, donc la première requête est juste un indice pur ref par rapport à 0 qui MySQL est au courant, tandis que le second contient une logique plus complexe que MySQL ne peut pas représenter comme expression sargable.

+0

+1 pour l'explication claire et technique. –

+0

+1 pour mentionner l'optimiseur –

+0

L'optimiseur MySQL est si faible que je suis surpris – Mask

0

Dans MySQL, le mot-clé FAUX est pas un morceau booléenne de données: il est un integer constant that equals zero. Au contraire, ! (aka NOT) est un opérateur logique que:

est évaluée à 1 si l'opérande est égal à 0, à 0 si l'opérande est non nulle, et NOT NULL retourne NULL.

Je suppose qu'il n'y a pas beaucoup de différence pratique:

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) 

Pourtant, ils ne sont pas des opérations identiques.

Questions connexes