Tengo una tabla InnoDB bastante ocupada (200,000 filas, supongo que algo así como decenas de consultas por segundo). Debido a un error, obtuve 14 filas con (la misma) direcciones de correo electrónico no válidas y quería eliminarlas.
Simplemente intenté DELETE FROM table WHERE email='invalid address'
y obtuve el "Tiempo de espera de bloqueo excedido" después de unos 50 segundos. Esto no es terriblemente sorprendente, ya que la columna de la fila no está indexada.
Sin embargo, luego lo hice SELECT id FROM table WHERE email='invalid address'
y eso tomó 1.25 segundos. Ejecutar DELETE FROM table WHERE id in (...)
, copiar y pegar los identificadores del resultado SELECCIONAR, tomó 0.02 segundos.
Que esta pasando? ¿Alguien puede explicar por qué ELIMINAR con la condición es tan lento que agota el tiempo de espera, pero hacer SELECCIONAR y luego eliminar por id es tan rápido?
Gracias.
EDITAR: Por solicitud, publiqué la estructura de la tabla y algunos explain
resultados. También debo tener en cuenta que no hay claves foráneas que se refieran a esta tabla.
Sin embargo, la situación me parece sencilla: tengo un campo no indexado con el que estoy seleccionando. Esto requiere escanear toda la tabla, pero no es terriblemente grande. id
es la clave principal, por lo que eliminar por id es muy rápido, como debería ser.
mysql> show create table ThreadNotification2 \G
*************************** 1. row ***************************
Table: ThreadNotification2
Create Table: CREATE TABLE `ThreadNotification2` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`alertId` bigint(20) DEFAULT NULL,
`day` int(11) NOT NULL,
`frequency` int(11) DEFAULT NULL,
`hour` int(11) NOT NULL,
`email` varchar(255) DEFAULT NULL,
`highlightedTitle` longtext,
`newReplies` bit(1) NOT NULL,
`numReplies` int(11) NOT NULL,
`postUrl` longtext,
`sendTime` datetime DEFAULT NULL,
`sent` bit(1) NOT NULL,
`snippet` longtext,
`label_id` bigint(20) DEFAULT NULL,
`organization_id` bigint(20) DEFAULT NULL,
`threadEntity_hash` varchar(255) DEFAULT NULL,
`user_uid` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK3991E9D279251FE` (`organization_id`),
KEY `FK3991E9D35FC0C96` (`label_id`),
KEY `FK3991E9D3FFC22CB` (`user_uid`),
KEY `FK3991E9D5376B351` (`threadEntity_hash`),
KEY `scheduleSentReplies` (`day`,`frequency`,`hour`,`sent`,`numReplies`),
KEY `sendTime` (`sendTime`),
CONSTRAINT `FK3991E9D279251FE` FOREIGN KEY (`organization_id`) REFERENCES `Organization` (`id`),
CONSTRAINT `FK3991E9D35FC0C96` FOREIGN KEY (`label_id`) REFERENCES `Label` (`id`),
CONSTRAINT `FK3991E9D3FFC22CB` FOREIGN KEY (`user_uid`) REFERENCES `User` (`uid`),
CONSTRAINT `FK3991E9D5376B351` FOREIGN KEY (`threadEntity_hash`) REFERENCES `ThreadEntity` (`hash`)
) ENGINE=InnoDB AUTO_INCREMENT=4461945 DEFAULT CHARSET=utf8
1 row in set (0.08 sec)
mysql> explain SELECT * FROM ThreadNotification2 WHERE email='invalid address';
+----+-------------+---------------------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | ThreadNotification2 | ALL | NULL | NULL | NULL | NULL | 197414 | Using where |
+----+-------------+---------------------+------+---------------+------+---------+------+--------+-------------+
1 row in set (0.03 sec)
mysql> explain select * from ThreadNotification2 where id in (3940042,3940237,3941132,3941255,3941362,3942535,3943064,3944134,3944228,3948122,3953081,3957876,3963849,3966951);
+----+-------------+---------------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | ThreadNotification2 | range | PRIMARY | PRIMARY | 8 | NULL | 14 | Using where |
+----+-------------+---------------------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> delete from ThreadNotification2 where email='invalid address';
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> select id from ThreadNotification2 where email='invalid address';
+---------+
| id |
+---------+
| 3940042 |
| 3940237 |
| 3941132 |
| 3941255 |
| 3941362 |
| 3942535 |
| 3943064 |
| 3944134 |
| 3944228 |
| 3948122 |
| 3953081 |
| 3957876 |
| 3963849 |
| 3966951 |
+---------+
14 rows in set (1.25 sec)
mysql> delete from ThreadNotification2 where id in (3940042,3940237,3941132,3941255,3941362,3942535,3943064,3944134,3944228,3948122,3953081,3957876,3963849,3966951);
Query OK, 14 rows affected (0.02 sec)
email
es no indexados, entonces ambos DELETE
y SELECT
debería funcionar igualmente lento. O bien: Usted dice que la mesa está muy consultada. Tal vez cuando DELETE
DELETE FROM ThreadNotification2 WHERE email='invalid address';
quizás ayudaría también ...
EXPLAIN DELETE FROM....
, no funcionará. Por lo que sé, funciona solo en SELECT
s.
SHOW CREATE TABLE
y probablemente unEXPLAIN...
también.