¿En qué punto debo dividir o dividir una tabla muy grande pero simple?

8

Nuestro sitio tiene algunas tablas grandes pero simples (INT, INT, FECHA) para estadísticas. Cada mesa tiene hasta 300,000,000 filas, y se hace más grande cada día.

El proveedor de hosting ha sugerido que dividamos o particionemos las tablas, y he visto esta recomendación en otras partes en numerosas ocasiones.

Sin embargo...

Estoy luchando por conciliar este consejo con la capacidad máxima establecida para SQL Server : un tamaño de base de datos de 524,272 terabytes, con filas de tabla limitadas solo por el "almacenamiento disponible".

Según esas cifras, la tabla descrita anteriormente podría tener fácilmente cientos de millones de filas (10 a la potencia de 303).

Ah, ja, podría decir, hay una diferencia entre CAPACIDAD y RENDIMIENTO.

Pero en casi todas las preguntas sobre el rendimiento de SQL Server la respuesta es "Depende ... del diseño de la tabla y el diseño de la consulta".

Por eso estoy haciendo esta pregunta. El diseño de la mesa no podría ser mucho más simple. Tampoco las consultas que son operaciones simples de conteo (*) basadas en un campo de ID indexado.

Martin Hansen Lennox
fuente
Particionar tablas es algo que planifica en el diseño de su base de datos, antes de escribir datos de preferencia. Es mucho más difícil y tedioso hacer esto después del hecho.
1
Depende más de su escenario: ¿está bien el rendimiento? ¿Puedes archivar algunos de los datos? ¿Son las tablas así de razonables para hacer copias de seguridad / restaurar de manera eficiente? ¿Están comprimidos? Hubiera sido bueno particionar desde el primer día, pero el siguiente mejor día es hoy si le preocupa el rendimiento futuro si desea seguir las mejores prácticas.
LowlyDBA
2
Creo que con esta cantidad de datos necesitará dividir su base de datos en el nivel arquitectónico, la base de datos OLTP y la base de datos OLAP. La base de datos de su aplicación "OLTP" solo debe mantener los datos mínimos necesarios para la aplicación y el negocio, el resto debe volcarse en los datos almacén "OLAP". En cuanto a la pregunta es cuándo debería comenzar a particionar sus tablas, eche un vistazo a este artículo de Kendra LittleHow To Decide if You Should Use Table Partitioning
M.Ali
3
El rendimiento nunca se reduce al hecho de que una mesa es grande. De hecho, lo que es grande para muchos es pequeño para algunos. Comprenda qué operaciones se están haciendo más rápido y cuáles más lento al realizar particiones. Particionar no es un cambio rápido. Es un cambio mayormente lento y algunas cosas se vuelven cegadoramente rápidas.
Usr
44
Recomiendo encarecidamente el video de capacitación MCM sobre particionamiento de Kimberly Tripp.
Paul White 9

Respuestas:

10

Hay una razón por la que el consejo general es que depende del diseño de la tabla y de las consultas sobre ella. Mi respuesta a tu otra publicación en Stack Exchange lo dice. Decir "consultas que son operaciones simples de conteo (*) basadas en un campo de ID indexado" no proporciona mucha información ya que no dice nada sobre la cardinalidad del conjunto de filas en consideración. Las cosas que puede hacer para mitigar los problemas (a partir de ahora percibidos) son:

  1. Fraccionamiento. Específicamente, sus datos parecen ser datos de tipo de registro. Supongo que desea obtener estadísticas por alguna unidad de tiempo (por ejemplo, "widgets por día" o "whozits por hora"). Particione por su cuanto (es decir, días u horas en los ejemplos anteriores) y mueva las particiones a grupos de archivos de solo lectura ocasionalmente

  2. En una nota relacionada, si los datos se escriben una sola vez, considere agregar previamente los datos una vez que el período de tiempo ya no esté activo. Es decir, ¿por qué debo seguir contando cuántos eventos ocurrieron en un día desde hace tres años si esos datos nunca van a cambiar? Una vez que termine el día, cuente todo en ese día, guárdelo en otro lugar y nunca lo vuelva a contar. De hecho, si nunca necesita los datos detallados (es decir, solo realiza agregaciones contra ellos), considere eliminarlos después de contarlos. Si implementa esta idea, puede ser aún más inteligente con índices filtrados que cubren solo el período "activo", lo que hará que sus consultas sean más rápidas porque no cubrirán la gran mayoría de sus datos

Pero, como sugiere mi consejo en la otra publicación, la única forma de saberlo con certeza es cargarlo con una cantidad razonable de datos y probarlo. Todo lo que podemos hacer aquí es decir lo que probablemente funcionará en el caso general. Sin los detalles de su hardware, sus datos y sus consultas, todo lo que podemos hacer es adivinar. Y es posible que, una vez que ejecute la prueba, le proponga que la respuesta es "no hay nada que hacer" porque funciona bien como está.

Ben Thul
fuente
Gracias Ben Estoy empezando a apreciar que hay más variables en juego de lo que pensaba. Y acepto que, prácticamente hablando, 'probarlo y ver' es el enfoque más sensato. Pero como SQL Server es esencialmente un programa (aunque sea muy complicado), una parte de mí está frustrada por esta falta de previsibilidad.
Martin Hansen Lennox
1
@MartinHansenLennox y Ben: Definitivamente estoy de acuerdo con el enfoque "pruébalo" en lugar de solo escuchar consejos o especulaciones personales. Pero, recomendaría declarar más explícitamente en ese párrafo lo que significa realmente probarlo. Es más que simplemente cargarlo y ejecutar consultas. Las pruebas deben incluir la adición incremental de datos para ver si / cómo cambian las cosas a medida que cambian las estadísticas y los índices se fragmentan, etc. E intente realizar copias de seguridad, restaurar, reconstruir índices, etc. Debe tenerse en cuenta que los índices particionados, a partir de 2012, ya no obtener una actualización de estado completa al reconstruir.
Solomon Rutzky
@MartinHansenLennox: Tiene razón en sentirse frustrado por el enfoque "pruébelo y vea". SQL Server es muy predecible y, al menos en teoría, es posible analizar el problema antes de intentarlo. Sin embargo, la cantidad de conocimientos previos necesarios para hacerlo a menudo hace que esto sea difícil.
Thomas Kejser
7

Tomaré un enfoque diferente y notaré que la partición ( en SQL Server ) es principalmente una característica de administración de datos con el rendimiento de la consulta como un posible resultado secundario, dependiendo de cómo lo administre . 1

Como se señaló en el artículo vinculado, el beneficio principal de la partición es que puede mover datos rápidamente mediante el cambio de partición . Por ejemplo, puede archivar datos "más fríos" para un almacenamiento más lento y mantener sus datos "calientes" en un almacenamiento rápido. A intervalos programados regularmente, puede archivar datos rápidamente al pasarlos a particiones de archivo sin tener que pasar por el proceso de esperar a que un ETL realice la transferencia. Sin embargo, como se señaló en uno de los primeros comentarios a su pregunta, esto requerirá una cuidadosa reflexión y planificación antes de implementarlo. Además, dependiendo de la edición de SQL Server que use (Enterprise), puede aprovechar la compresión de datos para comprimir particiones individuales.

En lo que respecta al rendimiento, puede cambiar la escalada de bloqueo a AUTO(el valor predeterminado es TABLE) así :

ALTER TABLE dbo.T1 SET (LOCK_ESCALATION = AUTO);
GO

Además, es posible que elimine la partición, pero sus patrones de consulta tendrían que ajustarse a un patrón muy específico y repetible dentro de su sistema: la clave de partición y la clave de agrupamiento y cualquier clave única se interconectan y son muy importantes . Si este equilibrio no se trata de manera reconocida y diseñada, terminará con pesadillas de rendimiento.

Con el advenimiento de SQL Server 2014, también puede aprovechar las estadísticas incrementales, lo cual es muy útil si monitorea y actualiza / crea proactivamente estadísticas en tablas grandes.

Entonces, ¿en qué punto debe dividirse una tabla? Eso depende de su carga de trabajo de consulta, el perfil de sus datos, pero lo más importante, depende de cuál de las características de administración de la partición debe aprovechar. El particionamiento no es para el rendimiento de las consultas, es principalmente para la administración y administración de datos.

swasheck
fuente
2
"Particionar no es para el rendimiento de las consultas, es principalmente para la administración y administración de datos", parece obvio cuando lo dices, pero nunca lo había entendido antes. Grandes enlaces por cierto, gracias
Martin Hansen Lennox
Gracias por mencionar que esta característica es principalmente para la administración y no para el rendimiento. Raramente veo que se mencione eso y es bastante frustrante.
Solomon Rutzky
1
@MartinHansenLennox: También hay excelentes usos de particionamiento para el rendimiento. Por ejemplo, si usa trucos de particionamiento hash y para valores que tienen baja cardinalidad.
Thomas Kejser
7

Antes de decidir qué tan grande desea que sea la partición, considere las implicaciones del plan de consulta de la partición. Desde una perspectiva puramente de rendimiento, las particiones sirven como una forma de índice de grano grueso. Esto puede proporcionar un rendimiento adicional, pero también es una fuente de regresiones de rendimiento, especialmente si la clave de partición no aparece en todas las consultas. A partir de aquí, supongo que ya ha hecho esta tarea (como parece que sí).

Una buena regla general para el tamaño de partición que desea es: aproximadamente la mitad del tamaño de la DRAM que tiene en la caja. La razón de esta recomendación es:

  1. Puede reconstruir los índices en la partición sin derramar tempdb. Esto es MUCHO más rápido que si usa el acceso al disco (incluso con SSD).
  2. Mientras realiza esta reconstrucción, aún puede mantener una partición completa (generalmente la última) en DRAM para mantener el rendimiento de su consulta avanzando muy bien.

En otras palabras, desea tener suficiente DRAM para contener dos particiones y el tamaño de partición que desee depende de la máquina en la que se ejecuta. Las máquinas más grandes pueden manejar cómodamente particiones más grandes.

Tenga en cuenta que esta guía también proporciona un tamaño mínimo para tempdb: Al menos el tamaño de su partición más grande (por lo que PUEDE derramar la creación del índice allí si no hay suficiente DRAM cuando reconstruye un índice).

Puede considerar tamaños de partición más pequeños que esto, pero si lo hace, esto generalmente está destinado a la optimización del rendimiento y no a la capacidad de administración de los datos.

Hay muchos otros trucos que puedes jugar con particiones. Por ejemplo, comprimir, agregar o usar el Factor de relleno 100 en particiones de solo lectura. Pero el principio básico sigue siendo: trate de mantener cada fragmento de datos que administra más pequeño que DRAM.

PD: Feliz de ver que no tomas "depende" como respuesta, siempre pide un método para obtener la respuesta.

Thomas Kejser
fuente
Gracias Thomas, buen consejo, particularmente aprecio las explicaciones sobre el tamaño de partición.
Martin Hansen Lennox
7

El particionamiento de tablas, como muchas otras características, se usa con bastante frecuencia (¿o posiblemente incluso con más frecuencia?) De manera inapropiada. Alguna de las advertencias que daría se ha indicado muy bien en la respuesta de @ swasheck .

Además, una alternativa a considerar son las vistas particionadas. Esta es una forma de mantener tablas completamente separadas pero uniéndolas juntas a través de UNION ALL en una vista. Cada tabla requiere una RESTRICCIÓN DE VERIFICACIÓN que impone qué rango de datos contiene cada tabla. El optimizador conoce esta construcción y solo debe acceder a las tablas subyacentes requeridas por una consulta usando la Vista (no recuerdo todos los requisitos para que este trabajo funcione según lo previsto, por lo tanto, consulte el enlace CREAR VISTA en la parte inferior, pero Lo configuré antes y no fue difícil hacer que funcionara como se esperaba).

Definitivamente hay algunas restricciones, y una desventaja principal es que es menos transparente en comparación con el Particionamiento de tabla. Sin embargo, un beneficio principal es que estas son tablas separadas y, por lo tanto, las estadísticas están completamente separadas, mientras que con una Tabla Particionada son para toda la tabla (incluso si, a partir de SQL Server 2014, puede actualizar las estadísticas por partición).

Si no va a utilizar el cambio de particiones dentro y fuera, debe considerar esta opción. Especialmente si los datos más antiguos no cambian mucho, ya que las tablas que contienen los datos más antiguos no necesitan que sus índices / estadísticas se actualicen con tanta frecuencia (o posiblemente si esos datos nunca cambian).

Otra desventaja de la partición de tablas que no se menciona o pasa desapercibida con demasiada frecuencia es que a partir de SQL Server 2012, ya no se obtienen ESTADÍSTICAS DE ACTUALIZACIÓN "gratuitas" CON FULLSCAN al reconstruir índices particionados. Todavía obtiene estas estadísticas de actualización con una reconstrucción en índices no particionados, que serían los índices en las tablas en una Vista particionada :).

Para obtener más información sobre las vistas particionadas, consulte la página de MSDN para CREAR VISTA y busque la sección sobre "Vistas particionadas" en "Comentarios".

Solomon Rutzky
fuente
2
Gran punto sobre las estadísticas de actualización. Las vistas indexadas resuelven muchos problemas de particionamiento si puede manejar el impacto del optimizador.
Thomas Kejser