¿Por qué podría espacio de datos de una tabla de tomar hasta 4x el tamaño de los datos en bruto?

dba.stackexchange https://dba.stackexchange.com/questions/5455

  •  16-10-2019
  •  | 
  •  

Pregunta

Tengo una tabla con 490 M filas y 55 GB de espacio de tabla, por lo que alrededor 167 bytes por fila. La tabla tiene tres columnas: una VARCHAR(100), un DATETIME2(0), y una SMALLINT. La longitud media del texto en el campo VARCHAR es de aproximadamente 21,5, por lo que los datos en bruto debe estar alrededor de 32 bytes por fila:. 22 + 2 para la VARCHAR, 6 para la DATETIME2, y 2 para el número entero de 16 bits

Tenga en cuenta que el espacio anterior es de datos solamente, no índices. Estoy usando el valor que aparece bajo Propiedades | almacenamiento | en general | espacio de datos.

Por supuesto que debe ser algunos de arriba, pero 135 bytes por fila parece mucho, sobre todo para una gran mesa. ¿Por qué puede ser esto? ¿Alguien más ha visto multiplicadores similares? ¿Qué factores pueden influir en la cantidad de espacio extra que se requiere?

Para la comparación, he intentado crear una tabla con dos campos INT y filas de 1 m. El espacio de datos requerida fue de 16,4 MB: 17 bytes por fila, en comparación con 8 bytes de datos en bruto. Otra tabla de prueba con un INT y una VARCHAR(100) poblada con el mismo texto que la mesa real utiliza 39 bytes por fila (44 K filas), en las que cabe esperar 28 más un poco.

Así que la tabla de producción tiene considerablemente más sobrecarga. Se debe esto a que es más grande? Yo esperaría tamaños de índice que es aproximadamente N * log (N), pero no veo por qué el espacio necesario para los datos reales de ser no lineal.

Gracias de antemano por cualquier punteros!

EDIT:

Todos los campos enumerados son NOT NULL. La mesa de verdad tiene una PK agrupado en el campo y el campo VARCHAR DATETIME2, en ese orden. Para las dos pruebas, la primera INT fue la PK (agrupado).

Si es importante: la tabla es un registro de resultados de ping. Los campos son URL, fecha de ping / hora, y la latencia en milisegundos. Datos se añaden constantemente, y nunca se actualiza, pero los datos se elimina periódicamente para cortarlo a sólo unos registros por hora por URL.

EDIT:

Una respuesta muy interesante aquí sugiere que, para un índice con mucha lectura y la escritura, la reconstrucción puede no ser beneficioso. En mi caso, el espacio consumido es una preocupación, pero si el rendimiento de escritura es más importante, uno puede ser mejor con índices flácidos.

¿Fue útil?

Solución

Después de discusiones en los comentarios sobre la pregunta original, que aparece en este caso el espacio perdido es causada por la elección de la clave agrupada, lo que ha llevado a la fragmentación masiva.

Siempre pena comprobar el estado de la fragmentación a través de sys.dm_db_index_physical_stats en estas situaciones.

Editar: Después de la actualización de los comentarios

La densidad media página (antes de reconstruir del índice agrupado) fue del 24%, que encaja perfectamente con la pregunta original. Las páginas fueron sólo 1/4 de su capacidad, por lo que el tamaño total fue de 4x el tamaño de los datos en bruto.

Otros consejos

Las estructuras de disco tienen gastos generales:

  • cabecera de la fila
  • nula mapa de bits + puntero
  • desplazamientos de columnas de longitud variable
  • punteros versión de fila (opcional)
  • ...

Tomar 2 x 4 bytes columnas int, tiene

  • 4 bytes de cabecera de la fila
  • 2 bytes puntero a NULL mapa de bits
  • 8 bytes para columnas 2 int
  • 3 bytes NULL mapa de bits

17 bytes Wow!

Puede lo mismo para su segunda tabla de prueba que tiene más sobrecarga como su original:

  • 2 bytes para el recuento de columnas de longitud variable
  • 2 bytes por columna de longitud variable

¿Por qué la diferencia? Además (no voy a enlazar a estos)

  • ¿alguna vez reconstruida índices para desfragmentar ellos?
  • No eliminaciones espacio de recuperación
  • páginas de datos se dividirá si se inserta en el centro
  • Las actualizaciones pueden causar adelante punteros (deja un espacio)
  • fila desbordamiento
  • columna varchar eliminado sin índice de reconstruir o DBCC CLEANTABLE
  • montón o tabla (montón no tiene índice agrupado = registros dispersos por todo)
  • RCSI nivel de aislamiento (extra 14 bytes por fila)
  • espacios finales (ANSI_PADDING SET está en ON por defecto) en varchar. Uso DATALENGTH a checl, no LEN
  • Ejecutar sp_spaceused con @updateusage = 'true'
  • ...

Consulte la siguiente: SQL Server: Cómo crear una tabla que llena una página de 8 KB

?

Desde SO:

Haga que los tipos de datos cambiado con el tiempo? Tiene columnas de longitud variable sido retirados? Han sido los índices desfragmentado menudo pero nunca reconstruida? Tienen una gran cantidad de filas sido eliminado o tienen una gran cantidad de columnas de longitud variable sido actualizado de manera significativa? Algunos buena discusión aquí .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a dba.stackexchange
scroll top