2009-02-04 16 views
6

Tengo una tabla maestra A, con ~ 9 millones de filas. Otra tabla B (misma estructura) tiene ~ 28K filas de la tabla A. ¿Cuál sería la mejor manera de eliminar todos los contenidos de B de la tabla A?¿Cómo puedo "restar" una tabla de otra?

La combinación de todas las columnas (~ 10) es única. Nada más en forma de una clave única.

Respuesta

6

Si tiene derechos suficientes, puede crear una nueva tabla y cambiarle el nombre a A. Para crear el nueva tabla puede usar la siguiente secuencia de comandos:

CREATE TABLE TEMP_A AS 
SELECT * 
FROM A 
MINUS 
SELECT * 
FROM B 

Esto debería funcionar bastante bien.

3
DELETE FROM TableA WHERE ID IN(SELECT ID FROM TableB) 

Debería funcionar. Aunque podría tomar un tiempo.

+1

usando una combinación en la eliminación probablemente sea más rápido – HLGEM

+1

Mi solución es una solución de desarrollador. No es una solución DBA de fancypants. :-D Pero me gusta aprender más sql. –

+0

no hay columna de id en ninguna de las tablas ... – Thorsten

2

una manera, simplemente enumerar todas las columnas

delete table a 
where exists (select 1 from table b where b.Col1= a.Col1 
AND b.Col2= a.Col2 
AND b.Col3= a.Col3 
AND b.Col4= a.Col4) 
+0

+1 por decir "unidireccional", no por su código real ... – gbn

+0

En mi humilde opinión, siempre es un hecho que es de una sola manera. Siempre hay más de 17 maneras para cualquier cosa. –

+0

AFAIK solo hay una forma de truncar una tabla (es decir, realizar una operación de eliminación mínimamente registrada) – SQLMenace

0

¿Hay un valor clave (o valores) que se puede utilizar?

algo así como

DELETE a 
FROM tableA a 
INNER JOIN tableB b 
on b.id = a.id 
+0

pls ver actualizado qn – Bajji

1
Delete t2 
from t1 
inner join t2 
    on t1.col1 = t2.col1 
    and t1.col2 = t2.col2 
    and t1.col3 = t2.col3 
    and t1.col4 = t2.col4 
    and t1.col5 = t2.col5 
    and t1.col6 = t2.col6 
    and t1.col7 = t2.col7 
    and t1.col8 = t2.col8 
    and t1.col9 = t2.col9 
    and t1.col10 = t2.col0 

Ésta es probable que sea muy lento, ya que tendría que tener cada COL indexada que es muy poco probable en un entorno cuando una tabla de este tamaño no tiene clave primaria, por lo hazlo fuera del pico. ¿Qué te llevó a tener una mesa con 9 millones de registros y sin clave principal?

+0

+1 para indicar que será lento ... – Thorsten

1

Si esto es algo que tendrá que hacer de forma regular, la primera opción debe ser intentar mejorar el diseño de la base de datos (buscando claves principales, tratando de que la condición de "unirse" esté activada). columnas como sea posible).

Si no es posible, la segunda opción distinta es determinar la "selectividad" de cada una de las columnas (es decir, cuántos valores "diferentes" tiene cada columna, 'nombre' sería más selectivo que 'dirección país 'que' hombre/mujer '). El tipo general de declaración yo sugeriría sería así:

Delete from tableA 
where exists (select * from tableB 
where tableA.colx1 = tableB.colx1 
and tableA.colx2 = tableB.colx2 
etc. and tableA.colx10 = tableB.colx10). 

La idea es hacer una lista de las columnas en el orden de la selectividad y construir un índice en colx1, etc. colx2 en TableB. El número exacto de columnas en la tabla B sería el resultado de alguna medida de prueba &. (Compensar el tiempo para construir el índice en la tabla B con el tiempo mejorado de la instrucción delete.)

Si esta es solo una operación de una sola vez, elegiría uno de los métodos lentos descritos anteriormente. Probablemente no valga la pena el esfuerzo de pensar demasiado sobre esto cuando puede simplemente comenzar un enunciado antes de irse a casa ...

+0

+1 para el primer y el último párrafo. – karlgrz

Cuestiones relacionadas