Tengo una tabla cats
con 42,795,120 filas.¿ELIMINAR SQL con una subconsulta correlacionada para la tabla con 42 millones de filas?
Aparentemente, esta es una gran cantidad de filas. Así que cuando hago:
/* owner_cats is a many-to-many join table */
DELETE FROM cats
WHERE cats.id_cat IN (
SELECT owner_cats.id_cat FROM owner_cats
WHERE owner_cats.id_owner = 1)
los tiempos de consulta fuera :(
(edición: Necesito aumentar mi valorCommandTimeout
, defecto es sólo 30 segundos)
I no puedo usar TRUNCATE TABLE cats
porque no quiero volar gatos de otros propietarios.
Estoy usando S "Simple" QL Server 2005 con "modelo de recuperación" ajustado a
Por lo tanto, pensé en hacer algo como esto (la ejecución de este SQL desde una aplicación por cierto):
DELETE TOP (25) PERCENT FROM cats
WHERE cats.id_cat IN (
SELECT owner_cats.id_cat FROM owner_cats
WHERE owner_cats.id_owner = 1)
DELETE TOP(50) PERCENT FROM cats
WHERE cats.id_cat IN (
SELECT owner_cats.id_cat FROM owner_cats
WHERE owner_cats.id_owner = 1)
DELETE FROM cats
WHERE cats.id_cat IN (
SELECT owner_cats.id_cat FROM owner_cats
WHERE owner_cats.id_owner = 1)
Mi pregunta es: ¿qué es el umbral de la cantidad de filas que puedo DELETE
en SQL Server 2005?
O, si mi enfoque no es óptimo, sugiera un mejor enfoque. Gracias.
Este post no me ayuda lo suficiente:
EDITAR (8/6/2010):
bien, me di cuenta después de leer el enlace de arriba otra vez que no tenía índices en estas tablas. Además, algunos de ustedes ya han señalado ese problema en los comentarios a continuación. Tenga en cuenta que este es un esquema ficticio, por lo que incluso id_cat
no es un PK, porque en mi esquema de la vida real, no es un campo único.
pondré índices en:
cats.id_cat
owner_cats.id_cat
owner_cats.id_owner
supongo que todavía estoy tomando la mano de este almacenamiento de datos, y obviamente necesito índices en todos los campos JOIN
¿verdad?
Sin embargo, me lleva horas realizar este proceso de carga por lotes. Ya lo estoy haciendo como SqlBulkCopy
(en fragmentos, no 42 mil a la vez). Tengo algunos índices y PKs.He leído los siguientes mensajes que confirma mi teoría de que los índices están desacelerando, incluso una copia masiva:
- SqlBulkCopy slow as molasses
- What’s the fastest way to bulk insert a lot of data in SQL Server (C# client)
así que voy a DROP
mis índices antes de la copia y luego re CREATE
cuando esté listo.
Debido a los largos tiempos de carga, me tomará un tiempo probar estas sugerencias. Informaré con los resultados.
ACTUALIZACIÓN (8/7/2010):
Tom sugirió:
DELETE
FROM cats c
WHERE EXISTS (SELECT 1
FROM owner_cats o
WHERE o.id_cat = c.id_cat
AND o.id_owner = 1)
Y aún sin índices, por 42 millones de filas, se tardó 13:21 min: s frente a 22 : 08 con la forma descrita arriba. Sin embargo, durante 13 millones de filas, lo tomó 2:13 frente a 2:10 a la antigua. Es una buena idea, ¡pero aún necesito usar índices!
Update (8/8/2010):
Algo está terriblemente mal! Ahora con los índices activados, mi primera consulta de eliminación anterior tomó 1: 9 horas: mín. (¡sí una hora!) versus 22:08 min: seg y 13:21 min: seg versus 2:10 min: seg para 42 mil filas y 13 mil filas respectivamente. Voy a probar la consulta de Tom con los índices ahora, pero esto va en la dirección incorrecta. Por favor ayuda.
Update (8/9/2010):
de Tom delete tomó 1:06 hrs: min durante 42 filas mil y 10:50 min: seg para 13 filas mil con índices frente a 13:21 min : sec y 2:13 min: seg respectivamente. ¡Las eliminaciones tardan más tiempo en mi base de datos cuando uso índices por un orden de magnitud! Creo que sé por qué, mi base de datos .mdf y .ldf creció de 3.5 GB a 40.6 GB durante la primera eliminación (42 mil)! ¿Qué estoy haciendo mal?
Update (8/10/2010):
A falta de cualquier otra opción, me han llegado con lo que siento es una solución mediocre (esperemos que temporal):
- Aumentar el tiempo de espera para la conexión a la base de datos de 1 hora (
CommandTimeout=60000;
defecto fue de 30 seg) - consulta de uso Tom:
DELETE FROM WHERE EXISTS (SELECT 1 ...)
, ya que lleva a cabo un poco más rápido DROP
todos los índices y PK antes de ejecutar la instrucción delete (???)- Run
DELETE
comunicado CREATE
todos los índices y PK
parece una locura, pero al menos es más rápido que usar TRUNCATE
y empezar de mi carga desde el principio con el primer owner_id
, porque uno de mi owner_id
tarda 2:30 h: min para cargar en comparación con 17:22 min: seg para el proceso de eliminación que acabo de describir con filas de 42 mil. (Nota: si mi proceso de carga arroja una excepción, empiezo de nuevo por ese owner_id
, pero no quiero volar el anterior owner_id
, así que no quiero TRUNCATE
la tabla owner_cats
, por lo cual intento utilizar DELETE
.)
aún más ayuda sería apreciada :)
¿Puede explicar lo que tiene para los índices en sus tablas? – bobs
No soy un enemigo de los gatos, pero no son muchas las filas, pero son muchos gatos :) Y, esto me rompe "No quiero que los gatos se deshagan de otros propietarios" – bobs
¿Esto es así? Base de datos CrazyOldLady? –