Tengo una instancia de SQL Server 2008 con aproximadamente 150 columnas. Anteriormente llené esta tabla con aproximadamente 12 millones de entradas, pero desde entonces la borré en preparación para un nuevo conjunto de datos.
Sin embargo, los comandos que una vez corrió al instante en una mesa vacía, como count(*)
y select top 1000
en SQL Management Studio
AHorA eones para funcionar.
SELECT COUNT(*) FROM TABLE_NAME
tardó más de 11 minutos en devolver 0 y SELECT TOP 1000
tardó casi 10 minutos en devolver una tabla vacía.
También he notado que el espacio libre en mi disco duro ha desaparecido literalmente (de alrededor de 100G a 20G). Lo único que sucedió fue una sola consulta que ejecuté:
DELETE FROM TABLE_NAME
¿¡¿Qué sucede?!?
TRUNCATE TABLE
lugar deDELETE FROM
.Respuestas:
Ya te han dicho por qué
TRUNCATE
sería mucho más rápido / mejor / más sexy queDELETE
, pero aún queda una pregunta por responder:¿Por qué es
SELECT
más lento después deDELETE
completar ?Eso es porque
DELETE
solo ha fantasmado las filas. La tabla es tan grande como cuando tenía 12 millones de filas, aunque no tiene ninguna. Para contar las filas (0), se necesita tanto tiempo como para contar 12 millones de filas. Con el tiempo, el proceso de limpieza de fantasmas recolectará basura estos registros fantasmas y desasignará páginas que contengan solo fantasmas, y sus SELECT se acelerarán. Pero en este momento, si se registra,Skipped Ghosted Records/sec
perfmon probablemente se dispare duranteSELECT COUNT(*)
. También podría acelerar las cosas mediante la reconstrucción de la tabla:ALTER TABLE ... REBUILD
.TRUNCATE
También se habría ocupado de este problema, ya que no deja fantasmas atrás.Consulte también Dentro del motor de almacenamiento: limpieza fantasma en profundidad .
fuente
DELETE
las instrucciones eliminan filas de una tabla de una en una, registrando cada fila en la tablatransaction log
y manteniendo lalog sequence number (LSN)
información. Como mencionó que su tabla tenía datos enormes (12 millones de registros), después de eliminar el disco duro, compruebe el tamaño del archivo de registro de la base de datos. Probablemente habría crecido.una mejor manera hubiera sido:
fuente
(Este fue originalmente un comentario a la respuesta de @ DaveE, pero lo puse en su propia respuesta porque se alargó)
TRUNCATE
Es una operación registrada. Tiene que ser de otra manera no es compatible con ACID. Sin embargo, las diferencias entreTRUNCATE
yDELETE
:TRUNCATE
solo registra páginas / extensiones * liberadas, mientras queDELETE
registra filas individuales.TRUNCATE
generalmente usará menos bloqueos, ya que requiere un bloqueo de tabla y bloqueos de página, en lugar deDELETE
usar bloqueos de fila **.IDENTITY
secuencias:TRUNCATE
restablece la secuencia de identidad en una tabla, si está presente.(* Una extensión = 8 páginas.
TRUNCATE
Registrará / eliminará extensiones si son todas de esa tabla, de lo contrario registrará / eliminará páginas de extensiones mixtas.** Un efecto secundario de esto es que
DELETE FROM TABLE
potencialmente puede dejar páginas vacías asignadas a la tabla, dependiendo de si la operación puede obtener un bloqueo exclusivo de la tabla o no).Entonces (volviendo a la pregunta original),
TRUNCATE TABLE
es definitivamente mejor queDELETE FROM TABLE
si está vaciando la tabla pero quiere mantener la estructura (NB:TRUNCATE
no se puede usar en una tabla a la que hace referencia una clave externa de otra tabla).Como se señaló en el comentario de @ Tullo, también verifique el modelo de recuperación de su base de datos: si está lleno, entonces debe comenzar a tomar copias de seguridad de registros o cambiar su modelo de recuperación a simple. Una vez que haya hecho cualquiera de estos, probablemente desee reducir su archivo de registro como una operación única (NB: solo archivo de registro ) para reclamar todo ese espacio libre.
Finalmente, otra cosa a tener en cuenta: estadísticas de tabla. ejecute
UPDATE STATISTICS <TABLENAME>' after
TRUNCATE/
DELETE` para que el optimizador de consultas no se vea afectado por estadísticas antiguas.fuente
(NOTA: no soy un DBA) DELETE es una operación registrada, y no libera el espacio utilizado. Probablemente tenga un registro de transacciones grande que ocupa espacio y escaneos de tablas ejecutándose en el espacio de tablas 'vacío'. Supongo que necesita borrar el registro de transacciones y reducir su base de datos. Este artículo de StackOverflow debería ayudarlo a comenzar.
Y use TRUNCATE TABLE cuando quiera hacer esto en el futuro.
EDITAR: Mi declaración sobre TRUNCATE no se registró fue un error. remoto.
fuente