¿Cómo afectarán los campos INCLUDE de gran índice al rendimiento del sistema?


15

Esta pregunta es sobre el rendimiento del índice de SQL Server con un varchar(2000)comoINCLUDE en un índice de cobertura.

Estoy tratando de mejorar el rendimiento en una aplicación de base de datos lenta e inestable. En algunos casos, se accede a los datos a través de grandes cadenas varchar, con las consultas, incluyendo las operaciones de cadena multple como SUBSTRING(), SPACE(), y DATALENGTH(). Aquí hay un ejemplo simplificado de acceso;

update fattable set col3 =  
   SUBSTRING(col3,1,10) + '*' + 
   SUBSTRING(col3,12,DATALENGTH(col3)-12)
from fattable where substring(col3,10,1) = 'A' and col2 = 2

El esquema se ve así:

CREATE TABLE [dbo].[FatTable]( 
    [id] [bigint] IDENTITY(1,1) NOT NULL, 
    [col1] [nchar](12) NOT NULL, 
    [col2] [int] NOT NULL, 
    [col3] [varchar](2000) NOT NULL, ... 

Se ha definido el siguiente índice, con un campo de cobertura en la columna de texto grande.

CREATE NONCLUSTERED INDEX [IndexCol2Col3] ON [dbo].[FatTable]  ( [col2] ASC ) 
    INCLUDE( [col3] )

Por lo que he leído, es MALO colocar grandes campos de datos en un índice. He estado leyendo varios artículos, incluyendo http://msdn.microsoft.com/en-us/library/ms190806.aspx, que analizan el impacto de la paginación y el tamaño del disco en el rendimiento del índice. Dicho esto, el plan de consulta definitivamente utiliza el índice de cobertura. No tengo suficiente información para determinar cuánto me está costando esto en términos de carga del sistema. Sé que, en general, el sistema está funcionando mal y me preocupa que este sea uno de los problemas. Preguntas:

  • ¿Es una buena idea poner esta varchar(2000)columna en el índice INCLUDE?

  • Dado que los INCLUDEcampos se almacenan en nodos hoja, ¿tienen mucho impacto en el rendimiento del índice?

Actualización: ¡Gracias por las excelentes respuestas! Esta es una pregunta injusta en algunos aspectos: como ustedes dicen, no hay una respuesta correcta absoluta sin estadísticas y perfiles reales. Como tantos problemas de rendimiento, supongo que la respuesta es "depende".


¿Cuánto duran los valores reales? Una VARCHAR(2000)que normalmente almacena solo diez caracteres es una cosa; Un sólido 2,000 bytes por registro es otra cosa.
Jon of All Trades

Solo una observación: Algo que "huele" aquí es que la columna grande puede contener 1) texto libre, en cuyo caso las consultas pueden beneficiarse de reescrituras para usar un índice FULLTEXT o 2) datos codificados "legibles por humanos" (por ejemplo, ampliamente inteligente teclas, como un VIN) que podrían beneficiarse de dividirse en columnas separadas o columnas calculadas persistentes con ÍNDICES. En otras palabras, el flujo de inteligencia y cambios de datos no está bien diseñado.
Graeme

1
Sí, #Graeme, hay un mal olor aquí, creo que se llama "legado". Hay una multitud de problemas en estas bases de datos.
RaoulRubin

Respuestas:


14

Alguna vez es una gran palabra, pero, en general, no, no pondría un campo varchar (2000) en INCLUIR.

Y sí, la forma en que se almacenan los datos a nivel de página puede afectar seriamente el rendimiento del índice, dependiendo de cómo se use el índice.

La cuestión es que, cuantas más filas de datos pueda incluir en una página, menos páginas tendrá que acceder, más rápido será su sistema, en su mayor parte. Agregar una columna realmente grande significa menos información almacenada en una página, por lo que, en el caso de búsquedas o escaneos de rango, se deben leer más páginas para recuperar los datos, lo que ralentiza seriamente las cosas.

Para saber con certeza si este es un problema en su consulta o en su sistema, tendría que controlar las lecturas, especialmente la cantidad de páginas que utiliza la consulta.


Gracias Grant Como mencioné otro comentario, la buena información de rendimiento es escasa, de ahí la pregunta abstracta. No tengo experiencia en monitorear los costos de rendimiento del tamaño de página. Mi presentimiento es que es un problema, veré si puedo obtener algunas estadísticas.
RaoulRubin

1
establecer estadísticas IO para la consulta le dirá mucho, las lecturas lógicas representan el número de páginas accedidas. También puede monitorear segundos / lectura desde los contadores de perfmon para obtener información general sobre el rendimiento.
Grant Fritchey

6

¿Puede revisar la clave de índice agrupada actual y quizás hacer col2la clave de índice agrupada en su lugar? De esta forma, obtiene el comportamiento de "inclusión" de cobertura (ya que los índices agrupados siempre "incluyen" todo) sin duplicar los datos. Esto, por supuesto, está sujeto a muchos ify but, sin embargo, quizás valga la pena considerarlo. Por supuesto, si el índice agrupado actual impone una restricción (clave primaria, única), dicha restricción debería trasladarse a un índice no agrupado.


Su sugerencia sobre el PK es una gran idea, aunque no podré aplicarla en este caso; el PK existente es necesario para otras consultas. (¡Esta es una técnica que mantendré en la caja de herramientas!)
RaoulRubin

4

Es dificil de responder. Todo dependerá de su relación lectura: escritura. ¿Ha probado una carga de trabajo o simulado un ciclo comercial completo en un sistema de prueba, con y sin la columna incluida? La búsqueda sin ella puede costar mucho, pero si está actualizando los datos con más frecuencia de lo que está leyendo, podría estar bien.


La lectura general frente a la actualización es principalmente equilibrada. Los problemas de organización y privacidad dificultan la obtención de estadísticas útiles y pruebas realistas. Dado que estamos volando en su mayoría ciegos, tenemos que mirar las cosas desde un punto de vista abstracto (de ahí esta pregunta). Las pruebas significarán impulsar cambios en la producción y observar resultados, muy arriesgado.
RaoulRubin

2
¿Y la mayoría de las lecturas realmente extraen esta VARCHAR(2000)columna, o está resolviendo el problema del rendimiento de una consulta muy específica que no representa la mayoría de las consultas? Como sugiere Grant si esta columna no se usa en muchas consultas, o si realmente causa problemas para las búsquedas, probablemente será mejor pagar el precio de la búsqueda cuando la necesite, pero no pagar el almacenamiento cuando no . Una vez más, es realmente difícil saber en qué lado de la cerca debe estar, ya que realmente no tenemos ningún detalle (e incluso más difícil porque no puede realizar pruebas, debe esforzarse por solucionarlo).
Aaron Bertrand

3

Sé que llego tarde a esta fiesta, pero indexaría exactamente las expresiones utilizadas para localizar filas, como la subcadena (col3,10,1). Si alguna vez se usa el col3 completo, indexaría CHECKSUM (col3) (entendiendo que podría haber colisiones, por supuesto).

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.