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 índiceINCLUDE
?Dado que los
INCLUDE
campos 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".
fuente
VARCHAR(2000)
que normalmente almacena solo diez caracteres es una cosa; Un sólido 2,000 bytes por registro es otra cosa.Respuestas:
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.
fuente
¿Puede revisar la clave de índice agrupada actual y quizás hacer
col2
la 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 muchosif
ybut
, 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.fuente
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.
fuente
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).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).
fuente