¿Se leen los campos "fuera de la fila" cuando se usa un índice agrupado?

10

Sé que cuando VARCHAR(MAX)/NVARCHAR(MAX)se usan columnas, los datos se almacenan out of the row: la fila de datos tendrá un puntero a otra ubicación donde se almacena el 'valor grande'.

Tengo las siguientes preguntas:

  1. ¿Se almacena cada campo out of the rowo solo maxlos?
  2. Si está utilizando el clustered indexde la tabla para leer el registro completo, ¿también se leen los campos almacenados fuera de la fila?

VARCHAR (MAX) o NVARCHAR (MAX) se considera como un "tipo de gran valor". Los tipos de valores grandes generalmente se almacenan 'fuera de fila'. Significa que el ...

gotqn
fuente
2
¿De dónde vino la última parte citada? No es correcto.
Paul White 9
3
El texto completo en el hilo original de MSDN (por Jacob Sebastian) es correcto. La "cita" de desbordamiento de pila pierde un poco de eso. La pequeña fracción de lo que citó anteriormente omite todos los bits importantes :)
Paul White 9

Respuestas:

13

Sé que cuando VARCHAR(MAX)/NVARCHAR(MAX)se usan columnas, los datos se almacenan fuera de la fila ...

En realidad, eso depende de la configuración de la large value types out of rowopción, que se puede configurar usando sp_tableoption. De la documentación :

Extracto de BOL

El valor predeterminado es que los MAXvalores se almacenen en fila , hasta 8000 bytes, si encajan. A menos que haya utilizado sp_tableoptionpara cambiar el valor predeterminado, sus MAXdatos probablemente se almacenarán en fila.

Dicho esto, es una mala práctica usar MAXtipos de datos para valores que nunca excederán los 8000 bytes; en su lugar, use un tipo que no sea MAX. Además de cualquier otra cosa, el rendimiento a menudo es significativamente peor cuando se trata de MAXtipos, porque SQL Server debe estar preparado para hacer frente a datos que pueden tener un tamaño de hasta 2 GB.

¿Cada campo se almacena fuera de la fila o solo los máximos?

Solo los MAXunos. Además, si una MAXcolumna de la fila anterior se mueve fuera de la fila, solo esa columna de esa fila se ve afectada. Se reemplaza en fila por un puntero a la LOBestructura fuera de fila . También hay circunstancias en las que las columnas que no son MAX pueden moverse fuera de la fila.

Si está utilizando el índice agrupado de la tabla para leer el registro completo, ¿también se leen los campos almacenados fuera de la fila?

El escaneo del índice agrupado solo atraviesa datos en fila. Si se necesitan datos fuera de la fila para la consulta, se busca utilizando el puntero en fila.

Paul White 9
fuente
¿Es esto siempre cierto Scanning the clustered index traverses only in-row data.? Por ejemplo, si desea mostrar los NVARCHAR(MAX)valores de campo, ¿cómo es posible trabajar solo con in-row-data(si los valores se almacenan fuera de la fila)? ¿O cuando está utilizando el índice agrupado (porque no hay un índice de cobertura) pero no va workcon el NVARCHAR(MAX)campo, el SQL Server es lo suficientemente inteligente como para ver eso y omitir la búsqueda de out-of-rowdatos?
gotqn
Gracias por la respuesta. Entonces, finalmente, si tiene dos columnas, inty nvarchar(max)está seleccionando solo la intcolumna, el servidor SQL no desperdicia recursos en readlos out-of-rowdatos, ya que sabe que no los va a usar.
gotqn
Muchas gracias. Eso es muy lindo. Parece que con el uso sp_tableoptionpuede eliminar de la tabla todo lo que no se usa con frecuencia para reducir el tamaño de la fila, cuando se realizan muchas búsquedas / escaneos de índices agrupados.
gotqn
3
@gotqn Sí. Off-row era el valor predeterminado para los antiguos tipos de LOB text, ntexty image. También puede almacenar los tipos grandes en una tabla separada, por supuesto.
Paul White 9
4

Este comportamiento para el almacenamiento de objetos grandes se puede controlar mediante la configuración de la tabla:

exec sp_tableoption N'MyTable', 'large value types out of row', <'ON' or 'OFF'>

La referencia en la documentación de SQL Server 2012 está en: http://msdn.microsoft.com/en-us/library/ms173530.aspx

Por lo tanto, puede controlar dónde se utiliza el espacio, en fila o almacenado fuera de fila.

RLF
fuente
Gracias, realmente no sabía que puedes controlar esto.
gotqn