sql >> Base de Datos >  >> RDS >> Sqlserver

Tutorial de particiones y particiones de tablas de SQL Server

Problema

En este artículo, nos centraremos en la demostración de la partición de tablas. La explicación más simple del particionamiento de tablas se puede denominar dividir tablas grandes en pequeñas. Este tema proporciona escalabilidad y manejabilidad.

¿Qué es la partición de tablas en SQL Server?

Supongamos que tenemos una mesa y crece día a día. En este caso, la tabla puede causar algunos problemas que deben resolverse siguiendo los pasos que se definen a continuación:

  • Mantenga esta mesa. Tomará mucho tiempo y consumirá más recursos (CPU, IO, etc.).
  • Copia de seguridad.
  • Problemas de bloqueo.

Debido a las razones mencionadas anteriormente, necesitamos una partición de tablas. Este enfoque tiene los siguientes beneficios:

  • Capacidad de administración:si separamos la tabla, podemos administrar cada partición de la tabla. Por ejemplo, podemos hacer solo una partición de la tabla.
  • Capacidad de archivado:algunas particiones de la tabla se usan solo por este motivo. No necesitamos hacer una copia de seguridad de esta partición de la tabla. Podemos usar una copia de seguridad de un grupo de archivos y hacer una copia de seguridad solo cambiando una partición de la tabla.
  • Rendimiento de consultas:el optimizador de consultas de SQL Server decide utilizar la eliminación de particiones. Significa que SQL Server no realiza ninguna búsqueda de la partición no relacionada de la tabla.

Particionamiento de tablas vertical y horizontal en SQL Server

La partición de tablas es un concepto general. Hay varios tipos de partición que funcionan para casos particulares. Los más esenciales y ampliamente utilizados son los dos enfoques:particiones verticales y particiones horizontales.

La especificidad de cada tipo refleja la esencia de una tabla como una estructura que consta de columnas y filas:

• La partición vertical divide la tabla en columnas.
• La partición horizontal divide la tabla en filas.

El ejemplo más típico de partición de tablas verticales es una tabla de empleados con sus detalles:nombres, correos electrónicos, números de teléfono, direcciones, cumpleaños, ocupaciones, salarios y toda otra información que pueda ser necesaria. Una parte de dichos datos es confidencial. Además, en la mayoría de los casos, los operadores solo necesitan algunos datos básicos como nombres y direcciones de correo electrónico.

La partición vertical crea varias tablas "más estrechas" con los datos necesarios a mano. Las consultas se dirigen a una parte específica solamente. De esta forma, las empresas reducen la carga, aceleran las tareas y se aseguran de que no se revelen datos confidenciales.

La partición horizontal de tablas da como resultado dividir una tabla general en varias más pequeñas, donde cada tabla de partículas tiene el mismo número de columnas, pero el número de filas es menor. Es un enfoque estándar para tablas excesivas con datos cronológicos.

Por ejemplo, una tabla con los datos de todo el año se puede dividir en secciones más pequeñas para cada mes o semana. Entonces, la consulta solo se referirá a una tabla más pequeña específica. La partición horizontal mejora la escalabilidad de los volúmenes de datos con su crecimiento. Las tablas particionadas seguirán siendo más pequeñas y fáciles de procesar.

Cualquier partición de tablas en el servidor SQL debe considerarse con cuidado. A veces, debe solicitar los datos de varias tablas particionadas a la vez, y luego necesitará JOIN en las consultas. Además, la partición vertical aún puede resultar en tablas grandes y tendrá que dividirlas más. En su trabajo, debe confiar en las decisiones para sus propósitos comerciales específicos.

Ahora que hemos aclarado el concepto de partición de tablas en SQL Server, es hora de proceder a la demostración.

Vamos a evitar cualquier secuencia de comandos T-SQL y manejar todos los pasos de partición de tablas con el asistente de partición de SQL Server.

¿Qué necesitas para hacer particiones de bases de datos SQL?

  • Base de datos de muestra de WideWorldImporters
  • Edición para desarrolladores de SQL Server 2017

La siguiente imagen nos muestra cómo diseñar una partición de mesa. Haremos una partición de la tabla por años y ubicaremos diferentes grupos de archivos.

En este paso, crearemos dos grupos de archivos (FG_2013, FG_2014). Haga clic derecho en una base de datos y luego haga clic en la pestaña Grupos de archivos.

Ahora, conectaremos los grupos de archivos a nuevos archivos pdf.

Nuestra estructura de almacenamiento de base de datos está lista para la partición de tablas. Localizaremos la tabla que queremos particionar e iniciaremos el asistente Crear partición.

En la captura de pantalla a continuación, seleccionaremos una columna en la que queremos aplicar la función de partición. La columna seleccionada es "Fecha de factura".

En las próximas dos pantallas, nombraremos una función de partición y un esquema de partición.

Una función de partición definirá cómo particionar las filas [Ventas].[Facturas] según la columna Fecha de factura.

Un esquema de partición definirá mapas para las filas de Ventas. Facturas a grupos de archivos.

Asigne las particiones a grupos de archivos y establezca los límites.

Límite izquierdo/derecho define el lado de cada intervalo de valor límite que puede ser izquierdo o derecho. Estableceremos límites como este y haremos clic en Estimar almacenamiento. Esta opción nos proporciona la información sobre el número de filas a ubicar en los límites.

Y finalmente, seleccionaremos Ejecutar inmediatamente y luego daremos clic en Siguiente.

Una vez que la operación sea exitosa, haga clic en Cerrar.

Como puede ver, nuestra tabla Sales.Invoices se ha particionado. Esta consulta mostrará los detalles de la tabla particionada.

SELECT
  OBJECT_SCHEMA_NAME(pstats.object_id) AS SchemaName
  ,OBJECT_NAME(pstats.object_id) AS TableName
  ,ps.name AS PartitionSchemeName
  ,ds.name AS PartitionFilegroupName
  ,pf.name AS PartitionFunctionName
  ,CASE pf.boundary_value_on_right WHEN 0 THEN 'Range Left' ELSE 'Range Right' END AS PartitionFunctionRange
  ,CASE pf.boundary_value_on_right WHEN 0 THEN 'Upper Boundary' ELSE 'Lower Boundary' END AS PartitionBoundary
  ,prv.value AS PartitionBoundaryValue
  ,c.name AS PartitionKey
  ,CASE 
    WHEN pf.boundary_value_on_right = 0 
    THEN c.name + ' > ' + CAST(ISNULL(LAG(prv.value) OVER(PARTITION BY pstats.object_id ORDER BY pstats.object_id, pstats.partition_number), 'Infinity') AS VARCHAR(100)) + ' and ' + c.name + ' <= ' + CAST(ISNULL(prv.value, 'Infinity') AS VARCHAR(100)) 
    ELSE c.name + ' >= ' + CAST(ISNULL(prv.value, 'Infinity') AS VARCHAR(100))  + ' and ' + c.name + ' < ' + CAST(ISNULL(LEAD(prv.value) OVER(PARTITION BY pstats.object_id ORDER BY pstats.object_id, pstats.partition_number), 'Infinity') AS VARCHAR(100))
  END AS PartitionRange
  ,pstats.partition_number AS PartitionNumber
  ,pstats.row_count AS PartitionRowCount
  ,p.data_compression_desc AS DataCompression
FROM sys.dm_db_partition_stats AS pstats
INNER JOIN sys.partitions AS p ON pstats.partition_id = p.partition_id
INNER JOIN sys.destination_data_spaces AS dds ON pstats.partition_number = dds.destination_id
INNER JOIN sys.data_spaces AS ds ON dds.data_space_id = ds.data_space_id
INNER JOIN sys.partition_schemes AS ps ON dds.partition_scheme_id = ps.data_space_id
INNER JOIN sys.partition_functions AS pf ON ps.function_id = pf.function_id
INNER JOIN sys.indexes AS i ON pstats.object_id = i.object_id AND pstats.index_id = i.index_id AND dds.partition_scheme_id = i.data_space_id AND i.type <= 1 /* Heap or Clustered Index */
INNER JOIN sys.index_columns AS ic ON i.index_id = ic.index_id AND i.object_id = ic.object_id AND ic.partition_ordinal > 0
INNER JOIN sys.columns AS c ON pstats.object_id = c.object_id AND ic.column_id = c.column_id
LEFT JOIN sys.partition_range_values AS prv ON pf.function_id = prv.function_id AND pstats.partition_number = (CASE pf.boundary_value_on_right WHEN 0 THEN prv.boundary_id ELSE (prv.boundary_id+1) END)
WHERE pstats.object_id = OBJECT_ID('Sales.Invoices')
ORDER BY TableName, PartitionNumber;

EM Rendimiento de partición de SQL Server

Compararemos el rendimiento de las tablas particionadas y no particionadas para la misma tabla. Para hacer esto, use la consulta a continuación y active Incluir plan de ejecución real.

DECLARE @Dt as date  = '20131231'
SELECT COUNT(InvoiceDate)
  FROM [Sales].[Invoices]
  where InvoiceDate < @Dt

Cuando examinamos el plan de ejecución, sabemos que incluye las propiedades "Particionado", "Recuento real de particiones" y "Acceso real particionado".

La propiedad dividida indica que esta tabla está habilitada para la partición.

El recuento real de particiones La propiedad es el número total de particiones que lee el motor de SQL Server.

El Acceso Particionado Real La propiedad son los números de partición evaluados por el motor de SQL Server. SQL Server elimina el acceso para otras particiones, ya que se denomina eliminación de partición y obtiene una ventaja en el rendimiento de las consultas.

Ahora, observe el plan de ejecución de la tabla sin particiones.

La principal diferencia entre estos dos planes de ejecución es Número de filas leídas porque esta propiedad indica cuántas filas se leen para esta consulta. Como puede ver en el siguiente gráfico de compresión, los valores de las tablas particionadas son demasiado bajos. Por esta razón, consumirá un IO bajo.

A continuación, ejecute la consulta y examine el plan de ejecución.

DECLARE @DtBeg as date  = '20140502'
DECLARE @DtEnd as date  = '20140701'

SELECT COUNT(InvoiceDate)
  FROM [Sales].[Invoices]
  where InvoiceDate between @DtBeg and @DtEnd

Escalamiento de bloqueo a nivel de partición

La escalada de bloqueo es un mecanismo que utiliza SQL Server Lock Manager. Dispone para bloquear un nivel de objetos. Cuando aumenta el número de filas a bloquear, el administrador de bloqueos cambia un objeto de bloqueo. Este es el nivel de jerarquía de escalada de bloqueo "Fila -> Página -> Tabla -> Base de datos". Pero, en la tabla particionada, podemos bloquear una partición a medida que aumenta la concurrencia y el rendimiento. El nivel predeterminado de escalada de bloqueo es "TABLA" en SQL Server.

Ejecute la consulta utilizando la siguiente instrucción UPDATE.

BEGIN TRAN
DECLARE @Dt as date  = '20131221'
UPDATE [Sales].[Invoices] SET CreditNoteReason = 'xxx'   where InvoiceDate < @Dt
SP_LOCK

El cuadro rojo define un bloqueo exclusivo que garantiza que no se puedan realizar varias actualizaciones en el mismo recurso al mismo tiempo. Ocurre en la tabla Facturas.

Ahora, configuraremos el modo de escalamiento para la tabla Sales.Invoices para automatizarlo y volver a ejecutar la consulta.

ALTER TABLE Sales.Invoices SET (LOCK_ESCALATION = AUTO)

Ahora, el cuadro rojo define el bloqueo exclusivo de sangría que protege los bloqueos exclusivos solicitados o adquiridos en algunos recursos inferiores en la jerarquía. En breve, este nivel de bloqueo nos permite actualizar o eliminar otras particiones de tablas. Eso significa que podemos iniciar otra actualización o insertar otra partición de la tabla.

En publicaciones anteriores, también exploramos el problema de cambiar entre particiones de tablas y proporcionamos el tutorial. Esta información puede ser de ayuda para usted si se ocupa de estos casos. Consulte el artículo para obtener más información.

Referencias

  1. Modos de bloqueo
  2. Tablas e índices particionados