2010-01-24 15 views

Respuesta

25

¿Quieres una DELETE con una cláusula WHERE: este es el estándar SQL.

Lo que puede hacer es por lotes elimina así:

SELECT 'Starting' --sets @@ROWCOUNT 
WHILE @@ROWCOUNT <> 0 
    DELETE TOP (xxx) MyTable WHERE ... 

O si desea eliminar un porcentaje muy alto de filas ...

SELECT col1, col2, ... INTO #Holdingtable 
      FROM MyTable WHERE ..opposite condition.. 
TRUNCATE TABLE MyTable 
INSERT MyTable (col1, col2, ...) 
      SELECT col1, col2, ... FROM #Holdingtable 
+0

gracias por su gbn solución. –

+1

Y si se trata de muchas transacciones, según el modelo de copia de seguridad y el tamaño de registro, haga más copias de seguridad de registros para liberar espacio en el registro ... –

+0

La retención de datos en tablas temporales le hará pagar más memoria. –

4

se puede hacer un par de cosas si desea eliminar parte de su tabla y no TRUNCATE.

podría seleccionar una parte de la mesa en una nueva tabla, a continuación, cambiar los dos, así:

SELECT * 
INTO tmp_MyTable 
FROM MyTable 
WHERE Key='Value' 

IF @@ROWCOUNT > 0 
BEGIN 
    EXEC sp_rename MyTable, old_MyTable, NULL 
    EXEC sp_rename tmp_MyTable, MyTable, NULL 
    TRUNCATE old_MyTable 
END 

En segundo lugar, si usted está utilizando el particionado, puede crear una tabla idéntica (vacío) en el mismo esquema de partición ... y si la tabla está particionada de acuerdo con su lógica de archivado/depuración, puede mover un bloque de partición desde la tabla principal a la nueva tabla y luego truncar la nueva tabla. Por ejemplo:

ALTER TABLE MyTable 
SWITCH PARTITION 15 TO purge_MyTable PARTITION 2 
GO; 

TRUNCATE TABLE purge_MyTable 

Ps. Las particiones están disponibles en SQL 2005/08 Ent.

Espero que esto ayude!

+0

buena respuesta. FYI, puede usar ALTER TABLE ..SWITCH sin particionar también, pero luego necesita 2 tablas discretas. – gbn

0

Sychare Jedko,

La ventaja de TRUNCATE es evitar la tala de todos y cada uno de eliminación en el archivo de registro. una instrucción TRUNCATE creará una sola entrada (en log) para todo el lote.

0

Acabo de toparme con un problema similar trabajando en una tabla de etapas que tenía problemas al escalar con bloqueos adecuados.

Como la tabla relevante solo se referencia en una ubicación para nosotros, simplemente reemplazamos esa referencia con una consulta para el nombre de la tabla dinámica, que se crea con un "seleccionar en" similar a lo sugerido por gbn.

Esto se puede mantener porque la tabla de etapas solo se referencia en un lugar en el código, y el gasto de la llamada de base de datos adicional junto con la creación de tabla se justifica en un contexto de depósito. Si solo tiene unos cientos de registros o hace referencia a la tabla en su código varias veces, entonces este enfoque puede no funcionar.

0

Al manejar millones de filas, prefiero tener una instrucción WHERE y usar SELECCIONAR EN una tabla de copia, eliminar la tabla original y cambiar el nombre de la copia (volver al nombre original).

Sin embargo, debe tener en cuenta cosas como llaves (FK), restricciones, etc. Pero al usar este método, evita el tamaño de badazz del registro y evita un gran consumo de tiempo de eliminación en fragmentos.

/Snedker

Cuestiones relacionadas