2010-03-25 2 views
9

Le due istruzioni hanno prestazioni totalmente diverso:Qual è la differenza tra! Col e col = false in 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 | 
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+ 

definizione Colonna e relativo indice per analisi aiutare:

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

risposta

3

MySQL non può utilizzare l'indice per WHERE !createIndexed, perché deve valutare NOT createIndexed per ogni riga , con una scansione della tabella.

5

Logicamente, queste operazioni sono le stesse, ma l'ottimizzatore di MySQL non è così intelligente da vedere createIndexed = 0 in NOT createIndexed.

FALSE in MySQL è solo sinonimo di 0 e TRUE è sinonimo di 1.

Questa condizione è falsa:

SELECT 2 = TRUE 

-- 
0 

, così la prima query è solo un puro confronto dell'indice ref a 0 cui MySQL è consapevole, mentre la seconda contiene la logica più complicato MySQL non può rappresentare come espressione sargabile.

+0

+1 per la spiegazione chiara e tecnica. –

+0

+1 per aver menzionato l'ottimizzatore –

+0

L'ottimizzatore MySQL è così debole che sono sorpreso – Mask

0

In MySQL, la parola FALSE non è un pezzo booleana dei dati: è un integer constant that equals zero. Anzi, ! (aka NOT) è un operatore logico che:

Viene posto a 1 se l'operando è 0, per 0 se l'operando è diverso da zero, e NON NULL restituisce NULL.

Suppongo che non c'è molta differenza pratica:

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) 

Eppure loro non sono operazioni identiche.