Consideraciones sobre el rendimiento: Spread filas en varias tablas vs concentrar todas las filas de una tabla

StackOverflow https://stackoverflow.com/questions/1142296

Pregunta

Consideraciones sobre el rendimiento: filas. Extendido en varias tablas vs concentrado de todas las filas de una tabla

Hola.

necesito para registrar información acerca de acerca de cada paso que se produce en la aplicación de una base de datos SQL. Hay ciertas tablas, quiero que el registro debe estar relacionada con: Producto - debe iniciar la sesión cuando un producto ha sido creado cambiado etc. Orden - Igual que el anterior Envío - misma etc., etc., etc.

Se necesitan los datos para ser recuperados a menudo.

Tengo algunas ideas sobre cómo hacerlo:

  1. Tener una tabla de registro que contendrá columnas para todas estas tablas, a continuación, cuando quiero representar los datos en la interfaz de usuario para un determinado producto va a hacer seleccionar * de registro en el que LogId = Producto.IDProducto. Yo sé que esto podría ser divertido tener muchos cols, pero tengo la sensación de que el rendimiento será mejor. En el otro lado habrá una gran cantidad de filas en esta tabla.
  2. Haga que muchas mesas de registro de cada tipo de registro (ProductLogs, OrderLogs etc.) Realmente no me gusta esta idea, ya que no es consistente y tiene muchas mesas con estructura misma no tiene sentido, pero (?) Que podría ser más rápido cuando se busca en una tabla que tiene una menor cantidad de filas (mi mal?).
  3. Según la declaración no. 1, lo que podía hacer una segunda tabla a uno los muchos que tendrá LogId, TableNameId y RowId cols, y hará referencia a una fila de registro para muchas filas de la tabla en el PP, que tendrá una UDF para recuperar los datos (por ejemplo, ID de registro 234 pertenece a la tabla de clientes en CustomerId 345 y a la tabla de productos, donde productId = RowId); Creo que esta es la mejor manera de hacerlo, pero de nuevo, puede haber una gran cantidad de filas, va a ralentizar la búsqueda? o esto es lo que se debe hacer, whatcha que decir? ...

Ejemplo de No. 3 en la lista anterior:

CREATE TABLE [dbo].[Log](
    [LogId] [int] IDENTITY(1,1) NOT NULL,
    [UserId] [int] NULL,
    [Description] [varchar](1024) NOT NULL,
 CONSTRAINT [PK_Log] PRIMARY KEY CLUSTERED 
(
    [LogId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[Log]  WITH CHECK ADD  CONSTRAINT [FK_Log_Table] FOREIGN KEY([UserId])
REFERENCES [dbo].[Table] ([TableId])
GO
ALTER TABLE [dbo].[Log] CHECK CONSTRAINT [FK_Log_Table]
---------------------------------------------------------------------
CREATE TABLE [dbo].[LogReference](
    [LogId] [int] NOT NULL,
    [TableName] [varchar](32) NOT NULL,
    [RowId] [int] NOT NULL,
 CONSTRAINT [PK_LogReference] PRIMARY KEY CLUSTERED 
(
    [LogId] ASC,
    [TableName] ASC,
    [RowId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[LogReference]  WITH CHECK ADD  CONSTRAINT [FK_LogReference_Log] FOREIGN KEY([LogId])
REFERENCES [dbo].[Log] ([LogId])
GO
ALTER TABLE [dbo].[LogReference] CHECK CONSTRAINT [FK_LogReference_Log]
---------------------------------------------------------------------
CREATE FUNCTION GetLog
(   
    @TableName varchar(32),
    @RowId int
)
RETURNS 
@Log TABLE
(       
    LogId int not null,
    UserId int not null,
    Description varchar(1024) not null
)
AS
BEGIN

INSERT INTO @Log
SELECT     [Log].LogId, [Log].UserId, [Log].Description
FROM         [Log] INNER JOIN
                      LogReference ON [Log].LogId = LogReference.LogId
WHERE     (LogReference.TableName = @TableName) AND (LogReference.RowId = @RowId)
    RETURN 
END
GO
¿Fue útil?

Solución

Sin duda para la opción 3, por varias razones:

Los datos deben estar en los campos de una tabla, no como un nombre de tabla (opción 2) o un nombre de campo (opción 1). De esta manera la base de datos se hace más fácil de trabajar y fácil de mantener.

tablas estrechas genrally un mejor desempeño. El número de filas tiene un menor impacto en el rendimiento que el número de campos.

Si usted tiene un campo para cada tabla (opción 1), es probable que obtener una gran cantidad de campos vacíos cuando sólo unos pocos de los cuadros se ven afectados por una operación.

Otros consejos

Tenga cuidado con bases de datos preoptimizing. La mayoría de las bases de datos son razonablemente rápido y algo complicado. Desea ejecutar una prueba de eficiencia en primer lugar.

En segundo lugar poner todo en una tabla hace que sea más probable que los resultados que desea están en la memoria caché que acelerará el rendimiento enormemente. Por desgracia, también hace que sea mucho más probable que usted tendrá que buscar una mesa gigantesca para encontrar lo que busca. Esto se puede solucionar en parte, con un índice, pero los índices no son gratuitos (que hacer la escritura más caro, por ejemplo).

Mi consejo sería hacer una prueba para ver si el rendimiento realmente importa y luego probar los diferentes escenarios para ver cuál es el más rápido.

Si usted está hablando de grandes volúmenes de datos (millones de filas +), por lo que recibirá un beneficio del uso de diferentes tablas para almacenarlos en.

por ejemplo. ejemplo básico 50 millones de entradas de registro, asumiendo 5 "tipos" diferentes de tabla de registro Es mejor tener 5 x 10 millones tablas fila de 1 x 50 millones de fila de la tabla

  • INSERT rendimiento será mejor con mesas individuales - índices en cada mesa serán más pequeñas y por lo tanto más rápido / más fácil que ser actualizado / mantenido como parte de la operación de inserción

  • LEER rendimiento será mejor con mesas individuales - menos datos para consulta, índices más pequeños para atravesar. Además, suena como que había necesidad de almacenar una columna adicional para identificar qué tipo de entrada del registro es un registro (Producto, envío ....)

  • MANTENIMIENTO en tablas más pequeñas es menos doloroso (estadísticas, el índice de desfragmentación / reconstrucción etc)

En esencia, se trata de partición de datos. A partir de SQL 2005 en adelante, se ha construido en el soporte para el particionado (ver aquí ) pero es necesario Enterprise Edition para que, básicamente, lo que le permite particionar los datos en una tabla para mejorar el rendimiento (por ejemplo, que tendría su una tabla de registro, y luego definir cómo los datos que contiene se particionan)

escuché una entrevista con uno de los arquitectos de eBay recientemente, que ha destacado la importancia de la partición cuando se necesita el rendimiento y la escalabilidad y estoy de acuerdo fuertemente basado en mis experiencias.

Trate de aplicar la capa de acceso a datos en una forma para que pueda cambiar de un modelo de base de datos a otro si es necesario -. De esa manera se acaba de elegir uno y la preocupación sobre las implicaciones de rendimiento posteriores

Sin hacer algunas pruebas de rendimiento y tener una idea exacta de los tipos de carga que su va a conseguir que va a ser difícil optimizar ya que el rendimiento depende de varios factores, tales como el número de lecturas, el número de escrituras y si el lecturas y escrituras es probable que el conflicto y la causa de bloqueo.

Mi preferencia sería la opción 1 por cierto -. Su forma más simple de hacer y hay una serie de ajustes que puede hacer para ayudar a fix varios tipos de problemas que pueda tener

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