La respuesta corta es sin: MySQL hace no le permiten añadir una cláusula WHERE
a la declaración TRUNCATE
. Aquí está MySQL's documentation sobre la declaración TRUNCATE
.
Pero la buena noticia es que puede (algo) solucionar esta limitación.
simple, seguro, limpio pero la solución lenta usando DELETE
En primer lugar, si la tabla es lo suficientemente pequeño, sólo tiene que utilizar la declaración DELETE
(que tenía que ser mencionado):
1. LOCK TABLE my_table WRITE;
2. DELETE FROM my_table WHERE my_date<DATE_SUB(NOW(), INTERVAL 1 MONTH);
3. UNLOCK TABLES;
Las declaraciones LOCK
y UNLOCK
no son obligatorias, pero acelerarán las cosas y evitarán posibles bloqueos.
Desafortunadamente, esto será muy lento si su tabla es grande ... y ya que está considerando usar la declaración TRUNCATE
, supongo que es porque su tabla es grande.
Así que aquí es una manera de solucionar el problema con la TRUNCATE
declaración:
solución simple, rápido, pero no seguro utilizando TRUNCATE
1. CREATE TABLE my_table_backup AS
SELECT * FROM my_table WHERE my_date>=DATE_SUB(NOW(), INTERVAL 1 MONTH);
2. TRUNCATE my_table;
3. LOCK TABLE my_table WRITE, my_table_backup WRITE;
4. INSERT INTO my_table SELECT * FROM my_table_backup;
5. UNLOCK TABLES;
6. DROP TABLE my_table_backup;
Desafortunadamente, esta solución es un poco peligroso si otros procesos están insertando registros en la tabla al mismo tiempo:
- any re el cable insertado entre los pasos 1 y 2 se perderá
- la instrucción
TRUNCATE
restablece el contador AUTO-INCREMENT
a cero. Por lo tanto, cualquier registro insertado entre los pasos 2 y 3 tendrá un ID que será más bajo que los ID anteriores e incluso podría entrar en conflicto con los ID insertados en el paso 4 (tenga en cuenta que el contador AUTO-INCREMENT
volverá al valor correcto después del paso 4).
Desafortunadamente, no es posible bloquear la mesa y truncarla. Pero podemos (de alguna manera) trabajar alrededor de esa limitación usando RENAME
.
solución de medio sencillo, rápido, seguro, pero ruidoso usando TRUNCATE
1. RENAME TABLE my_table TO my_table_work;
2. CREATE TABLE my_table_backup AS
SELECT * FROM my_table_work WHERE my_date>DATE_SUB(NOW(), INTERVAL 1 MONTH);
3. TRUNCATE my_table_work;
4. LOCK TABLE my_table_work WRITE, my_table_backup WRITE;
5. INSERT INTO my_table_work SELECT * FROM my_table_backup;
6. UNLOCK TABLES;
7. RENAME TABLE my_table_work TO my_table;
8. DROP TABLE my_table_backup;
Esto debe ser completamente seguro y bastante rápido. El único problema es que otros procesos verán desaparecer la tabla my_table
durante unos segundos. Esto puede llevar a que se muestren errores en los registros en todas partes. Entonces, es una solución segura, pero es "ruidosa".
Descargo de responsabilidad: No soy un experto en MySQL, por lo que estas soluciones podrían ser realmente asquerosas. La única garantía que puedo ofrecer es que funcionen bien para mí. Si algún experto puede comentar sobre estas soluciones, le agradecería.
, gracias, asumiendo esa condición, ¿Cómo puedo evitar últimos 10 datos de días y elimine el resto (por ejemplo, la tabla tiene 10 millones de registros) de manera optimizada. – Sharpeye500
La velocidad de TRUNCATE se debe a que no escribe en los registros –