Si utilizza MySQL 5.5.42.MySQL (id> = N AND col2 IS NULL) query inaspettatamente lenta per grande N
Abbiamo una tabella publications
contenente circa 150 milioni di righe (circa 140 GB su un SSD).
La tabella include più colonne, di cui due sono di particolare interesse:
id
è la chiave primaria della tabella ed è di tipobigint
cluster_id
è una colonna Null di tipobigint
Entrambe le colonne hanno il proprio indice (separato).
Facciamo domande del modulo
SELECT * FROM publications
WHERE id >= 14032924480302800156 AND cluster_id IS NULL
ORDER BY id
LIMIT 0, 200;
Ecco il problema: Maggiore è il valore
id
(14032924480302800156 nell'esempio di cui sopra), più lenta è la richiesta.
In altre parole, le richieste di basso valore id
sono veloci (< 0,1 s), ma maggiore è il valore id
, più lenta è la richiesta (fino a minuti).
Tutto va bene se si utilizza un'altra colonna (indicizzata) nella clausola WHERE
. Per esempio
SELECT * FROM publications
WHERE inserted_at >= '2014-06-20 19:30:25' AND cluster_id IS NULL
ORDER BY inserted_at
LIMIT 0, 200;
dove inserted_at
è di tipo timestamp
.
Edit:
uscita di EXPLAIN
quando si utilizza id >= 14032924480302800156
:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
---+-------------+--------------+------+--------------------+------------+---------+-------+----------+------------
1 | SIMPLE | publications | ref | PRIMARY,cluster_id | cluster_id | 9 | const | 71647796 | Using where
uscita di EXPLAIN
quando si utilizza inserted_at >= '2014-06-20 19:30:25'
:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
---+-------------+--------------+------+------------------------+------------+---------+-------+----------+------------
1 | SIMPLE | publications | ref | inserted_at,cluster_id | cluster_id | 9 | const | 71647796 | Using where
Forse per 'id' più grandi, è più raro che' cluster_id' corrisponda al valore richiesto ('NULL')? In questo caso per 'id' più grandi il database potrebbe dover attraversare più record per selezionare il 200 richiesto con' cluster_id IS NULL'. –
Mostra l'output di [EXPLAIN] (https://dev.mysql.com/doc/refman/5.0/en/explain.html) sia per l'utilizzo di ID piccoli e grandi. –
@SergeRogatch Questa è un'osservazione eccellente, e ci abbiamo pensato, ma trovo difficile credere che ciò spiegherebbe rallentamenti di tre ordini di grandezza. –