2010-07-27 17 views
12

Necesito consultar una declaración de eliminación para la misma tabla en función de las condiciones de columna de la misma tabla para una subconsulta correlacionada.Eliminar declaración en la misma tabla

No puedo ejecutar directamente una declaración de eliminación y verificar una condición para la misma tabla en mysql para una subconsulta correlacionada.

Quiero saber si el uso de la tabla temporal afectará la memoria/el rendimiento de mysql?

Cualquier ayuda será muy apreciada.

Gracias.

+0

¿Por qué no puedes 'ejecutar directamente una declaración de eliminación y verificar una condición para la misma tabla'? –

Respuesta

13

Su pregunta es realmente no está claro, pero yo supongo que tienes una subconsulta correlacionada y usted está teniendo problemas para hacer un SELECT de la misma tabla que está bloqueado por la eliminación. Por ejemplo, para eliminar todas las revisiones menos la más reciente de un documento:

DELETE FROM document_revisions d1 WHERE edit_date < 
    (SELECT MAX(edit_date) FROM document_revisions d2 
    WHERE d2.document_id = d1.document_id); 

Esto es un problema para MySQL.

Hay muchos ejemplos de este tipo de problemas se pueden resolver usando MySQL multi-mesa borrar sintaxis:

DELETE d1 FROM document_revisions d1 JOIN document_revisions d2 
    ON d1.document_id = d2.document_id AND d1.edit_date < d2.edit_date; 

Pero estas soluciones están diseñadas mejor sobre una base caso por caso, por lo que si edita su pregunta y sea más específico sobre el problema que está tratando de resolver, quizás podamos ayudarlo.

En otros casos, puede que tenga razón, usar una tabla de temperatura es la solución más simple.

+0

Cuenta de agradecimiento, sí lo hizo bien, estoy teniendo problemas para ejecutar la eliminación de subconsulta correlacionada en mysql. Si uso la sintaxis de eliminación de tablas múltiples, de inmediato obtengo esta consulta en el registro lento de consultas. (supongamos que tiene 50K registros en la tabla que está eliminando; si realizo una comprobación de condición utilizando la sintaxis de eliminación múltiple, obtengo inmediatamente esta consulta en el registro lento de consultas). Así que fui al concepto de tabla temporal, mi pregunta es ¿afectará la tabla temporal a la memoria/rendimiento de MySQL? – Sharpeye500

+0

Por supuesto, una tabla temporal requiere una cierta cantidad de recursos, pero tenga en cuenta que MySQL crea tablas temporales sobre la marcha para consultas todo el tiempo. Y la tabla temporal se libera cuando se cierra la conexión actual de mysql, por lo que son bastante efímeras. –

+0

Sin embargo, le sugiero que investigue por qué su eliminación de tablas múltiples fue muy lenta. Es bastante sencillo escribir un SELECCIONAR equivalente que haga la misma combinación, y luego puede usar EXPLAIN para analizar el plan de optimización para SELECT (MySQL's EXPLAIN no admite DELETE). Es posible que pueda crear el índice de cobertura correcto para hacer que el DELETE se ejecute rápidamente. –

0

Puede borrar de la misma tabla. Eliminar comunicado es el siguiente

DELETE FROM table_name 
WHERE some_column=some_value 
1

no se puede ejecutar directamente una instrucción de eliminación y comprobar una condición para la misma tabla

Claro que puedes. Si desea eliminar de tabla1 mientras se comprueba la condición de que col1 = 'somevalue', usted puede hacer esto:

DELETE 
    FROM table1 
WHERE col1 = 'somevalue' 

EDITAR
Para eliminar utilizando una consulta correlacionada, consulte el siguiente ejemplo:

create table project (id int); 
create table emp_project (id int, project_id int); 

insert into project values (1); 
insert into project values (2); 
insert into emp_project values (100, 1); 
insert into emp_project values (200, 1); 

/* Delete any project record that doesn't have associated emp_project records */ 
DELETE 
    FROM project 
WHERE NOT EXISTS 
    (SELECT * 
     FROM emp_project e 
     WHERE e.project_id = project.id); 


/* project 2 doesn't have any emp_project records, so it was deleted, now 
    we have 1 project record remaining */ 
SELECT * FROM project; 

Result: 
id 
1 
+0

oops ... me hiciste parecer tonto :-) pero me perdí este punto, es decir. para subconsultas Eliminar en DONDE EN (SELECCIONAR DE DONDE NO EN (SELECT DE GROUP BY ORDER BY ) Esta consulta tarda más tiempo cuando los registros son altos, mi consulta es hacer Esta tabla temporal usará el nivel de rendimiento de mysql o mejorará si se hace usando la tabla temporal. es decir, obtener los valores de la subconsulta e insertar en una tabla temporal y ejecutar una declaración de eliminación en la condición IN se comprobará con select col1 de temp. – Sharpeye500

+0

@Sharpeye - Lo siento, no lo hice tengo la intención de hacerte parecer tonto, pensé que era tu verdadera pregunta. De todos modos, sería bueno si puede publicar un ejemplo de datos, es decir, mostrarnos los registros que existen antes y los registros que espera sean eliminados. Entonces podremos ayudar más. – dcp

+0

Gracias por corregir mi pregunta, he editado ahora. – Sharpeye500

0

Crea una tabla temporal con los valores que deseas eliminar, luego únela a la tabla mientras borras. En este ejemplo, tengo una tabla "Juegos" con una columna de ID. Eliminaré identificadores mayores a 3. Reuniré los objetivos en una tabla temporal primero para poder informar sobre ellos más tarde.

DECLARE @DeletedRows TABLE (ID int) 

insert 
    @DeletedRows 
     (ID) 
select 
    ID 
from 
    Games 
where 
    ID > 3 


DELETE 
    Games 
from 
    Games g 
join 
    @DeletedRows x 
    on x.ID = g.ID 
+1

Gracias Carter, pero esto afectará el rendimiento de MySQL? por ej. Digamos que si tienes 1000 usuarios en tu sitio, si todos ellos comienzan a crear tablas temporales en su inicio de sesión, ¿qué pasará con la memoria caché/tabla de tabla, aumentará correctamente? – Sharpeye500

+0

Solo está creando una tabla en la memoria. Utilizará más recursos que simplemente eliminar las filas normalmente, pero si desea informar sobre los registros eliminados, es la única forma. Solo utiliza la memoria para almacenar los ID de los registros que va a eliminar. –

19

Puede hacer que mysql haga la tabla temporal por usted ajustando su consulta de "dónde" como en línea desde la tabla.

Esta búsqueda original le dará el temido "No se puede especificar la tabla de destino para la actualización de cláusula":

DELETE FROM sametable 
WHERE id IN (
    SELECT id FROM sametable WHERE stuff=true 
) 

Reescribiendo a utilizar temp en línea se convierte en ...

DELETE FROM sametable 
WHERE id IN (
SELECT implicitTemp.id from (SELECT id FROM sametable WHERE stuff=true) implicitTemp 
) 
+0

Encontré esto dio como resultado una consulta muy lenta. No estoy seguro de qué tan lento porque me di por vencido después de 1-3 minutos. Usar un JOIN como lo sugirió Bill Karwin fue de aproximadamente 100 ms. – phylae

Cuestiones relacionadas