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

Mejore el rendimiento de las consultas de SQL Server en tablas grandes

Respuesta sencilla:NO. No puede admitir consultas ad hoc en una tabla de 238 columnas con un factor de relleno del 50 % en el índice agrupado.

Respuesta detallada:

Como he dicho en otras respuestas sobre este tema, el diseño de índices es a la vez arte y ciencia y hay tantos factores a considerar que hay pocas reglas estrictas y rápidas, si es que hay alguna. Debe tener en cuenta:el volumen de operaciones DML frente a SELECT, subsistema de disco, otros índices/disparadores en la tabla, distribución de datos dentro de la tabla, son consultas que usan condiciones SARGable WHERE y varias otras cosas que ni siquiera puedo recordar correctamente ahora.

Puedo decir que no se puede brindar ayuda para las preguntas sobre este tema sin una comprensión de la Tabla en sí, sus índices, disparadores, etc. 99% del problema) Puedo ofrecer algunas sugerencias.

Primero, si la definición de la tabla es precisa (238 columnas, factor de relleno del 50 %), entonces puede ignorar el resto de las respuestas/consejos aquí;-). Lamento ser menos que político aquí, pero en serio, es una búsqueda inútil sin conocer los detalles. Y ahora que vemos la definición de la tabla, queda un poco más claro por qué una consulta simple tardaría tanto, incluso cuando las consultas de prueba (Actualización n.º 1) se ejecutaron tan rápidamente.

El principal problema aquí (y en muchas situaciones de bajo rendimiento) es un mal modelado de datos. 238 columnas no está prohibido al igual que tener 999 índices no está prohibido, pero generalmente tampoco es muy inteligente.

Recomendaciones:

  1. Primero, esta mesa realmente necesita ser remodelada. Si se trata de una tabla de almacenamiento de datos, entonces tal vez, pero si no es así, estos campos realmente deben dividirse en varias tablas que pueden tener el mismo PK. Tendría una tabla de registro maestra y las tablas secundarias son solo información dependiente basada en atributos comúnmente asociados y el PK de esas tablas es el mismo que el PK de la tabla maestra y, por lo tanto, también FK a la tabla maestra. Habrá una relación de 1 a 1 entre el maestro y todas las tablas secundarias.
  2. El uso de ANSI_PADDING OFF es preocupante, sin mencionar la inconsistencia dentro de la tabla debido a las diversas adiciones de columnas a lo largo del tiempo. No estoy seguro de que puedas solucionarlo ahora, pero lo ideal sería que siempre tuvieras ANSI_PADDING ON , o al menos tener la misma configuración en todos los ALTER TABLE declaraciones.
  3. Considere crear 2 grupos de archivos adicionales:tablas e índices. Es mejor no poner tus cosas en PRIMARY ya que ahí es donde SQL SERVER almacena todos sus datos y metadatos sobre sus objetos. Usted crea su tabla e índice agrupado (ya que esos son los datos de la tabla) en [Tables] y todos los índices no agrupados en [Indexes]
  4. Aumenta el factor de relleno del 50 %. Es probable que este número bajo sea la razón por la que su espacio de índice es más grande que su espacio de datos. Al hacer una Reconstrucción de índice, se recrearán las páginas de datos con un máximo de 4k (del tamaño total de página de 8k) utilizadas para sus datos, de modo que su tabla se distribuya en un área amplia.
  5. Si la mayoría o todas las consultas tienen "ER101_ORG_CODE" en WHERE condición, luego considere mover eso a la columna principal del índice agrupado. Suponiendo que se use con más frecuencia que "ER101_ORD_NBR". Si "ER101_ORD_NBR" se usa con más frecuencia, consérvelo. Simplemente parece, asumiendo que los nombres de campo significan "Código de organización" y "Número de pedido", que "Código de organización" es una mejor agrupación que podría tener múltiples "Números de pedido" dentro de él.
  6. Punto menor, pero si "ER101_ORG_CODE" siempre tiene 2 caracteres, entonces use CHAR(2) en lugar de VARCHAR(2) ya que guardará un byte en el encabezado de la fila que rastrea los tamaños de ancho variable y suma millones de filas.
  7. Como han mencionado otros aquí, usando SELECT * dañará el rendimiento. No solo porque requiere que SQL Server devuelva todas las columnas y, por lo tanto, es más probable que realice un escaneo de índice agrupado independientemente de sus otros índices, sino que también le toma tiempo a SQL Server ir a la definición de la tabla y traducir * en todos los nombres de columna. Debería ser ligeramente más rápido para especificar los 238 nombres de columna en SELECT sin embargo, eso no ayudará con el problema de escaneo. Pero, ¿alguna vez realmente necesitas las 238 columnas al mismo tiempo de todos modos?

¡Buena suerte!

ACTUALIZAR
Para completar la pregunta "cómo mejorar el rendimiento en una tabla grande para consultas ad-hoc", se debe tener en cuenta que, si bien no ayudará en este caso específico, SI alguien está usando SQL Server 2012 (o más reciente cuando llegue ese momento) y SI la tabla no se está actualizando, entonces usar Índices de almacén de columnas es una opción. Para obtener más detalles sobre esa nueva función, consulte aquí:http://msdn.microsoft.com/en-us/library/gg492088.aspx (creo que se crearon para poder actualizarse a partir de SQL Server 2014).

ACTUALIZACIÓN 2
Las consideraciones adicionales son:

  • Habilite la compresión en el índice agrupado. Esta opción estuvo disponible en SQL Server 2008, pero como una función exclusiva de Enterprise Edition. Sin embargo, a partir de SQL Server 2016 SP1 , ¡La compresión de datos estuvo disponible en todas las ediciones! Consulte la página de MSDN para la compresión de datos para obtener detalles sobre la compresión de filas y páginas.
  • Si no puede usar la compresión de datos, o si no proporciona muchos beneficios para una tabla en particular, SI tiene una columna de tipo de longitud fija (INT , BIGINT , TINYINT , SMALLINT , CHAR , NCHAR , BINARY , DATETIME , SMALLDATETIME , MONEY , etc) y más del 50% de las filas son NULL , luego considere habilitar SPARSE opción que estuvo disponible en SQL Server 2008. Consulte la página de MSDN para usar columnas dispersas para obtener detalles.