Os campos "fora da linha" são lidos quando um índice clusterizado é usado?

10

Eu sei que quando as VARCHAR(MAX)/NVARCHAR(MAX)colunas são usadas, os dados são armazenados out of the row- a linha de dados terá um ponteiro para outro local onde o 'valor grande' é armazenado.

Tenho as seguintes perguntas:

  1. Cada campo é armazenado out of the rowou apenas esses max?
  2. Se você estiver usando o clustered indexda tabela para ler o registro inteiro, os campos que são armazenados fora da linha também serão lidos?

VARCHAR (MAX) ou NVARCHAR (MAX) é considerado como um 'tipo de valor grande'. Tipos de valores grandes geralmente são armazenados 'fora da linha'. Isso significa que o ...

gotqn
fonte
2
De onde veio esse último pedaço citado? Não está correto.
Paul White 9
3
O texto completo no thread original do MSDN (por Jacob Sebastian) está correto. A "citação" do Stack Overflow perde bastante disso. A pequena fração do que você citou acima omite todos os bits importantes :)
Paul White 9

Respostas:

13

Eu sei que quando as VARCHAR(MAX)/NVARCHAR(MAX)colunas são usadas, os dados são armazenados fora da linha ...

Na verdade, isso depende da configuração da large value types out of rowopção, que pode ser definida usando sp_tableoption. A partir da documentação :

Extrato de BOL

O padrão é que os MAXvalores sejam armazenados em linha , até 8000 bytes, se eles se ajustarem. A menos que você tenha usado sp_tableoptionpara alterar o padrão, seus MAXdados provavelmente serão armazenados em linha.

Dito isso, é uma prática ruim usar MAXtipos de dados para valores que nunca excederão 8000 bytes - use um tipo não MAX. Além de qualquer outra coisa, o desempenho costuma ser significativamente menor ao lidar com MAXtipos, porque o SQL Server deve estar preparado para lidar com dados que podem ter até 2 GB de tamanho.

Cada campo é armazenado fora da linha ou apenas no máximo?

Somente MAXos. Além disso, se uma MAXcoluna anteriormente na linha for movida para fora da linha, somente essa coluna nessa linha será afetada. É substituído na linha por um ponteiro para a LOBestrutura fora da linha . Há também circunstâncias em que colunas não MAX podem ser movidas para fora da linha.

Se você estiver usando o índice clusterizado da tabela para ler o registro inteiro, os campos armazenados fora da linha também serão lidos?

A varredura do índice clusterizado percorre apenas dados em linha. Se forem necessários dados fora da linha para a consulta, eles serão procurados usando o ponteiro na linha.

Paul White 9
fonte
Isso sempre é verdade - Scanning the clustered index traverses only in-row data.? Por exemplo, se você deseja exibir os NVARCHAR(MAX)valores do campo, como é possível trabalhar apenas com o in-row-data(se os valores estiverem armazenados fora da linha)? Ou quando você estiver usando o índice em cluster (porque não há índice de cobertura), mas não estiver workusando o NVARCHAR(MAX)campo, o SQL Server é inteligente o suficiente para ver isso e ignorar a pesquisa de out-of-rowdados?
gotqn
Obrigado pela resposta. Então, finalmente, se você tiver duas colunas - inte nvarchar(max)você estiver selecionando apenas a intcoluna, o SQL-Server não desperdiçará recursos para reados out-of-rowdados, pois sabe que você não os usará?
gotqn
Muito obrigado. Isso é muito simpático. Parece que, usando o sp_tableoptionvocê, é possível colocar fora da tabela tudo o que geralmente não é usado para reduzir o tamanho da linha, quando muitas buscas / verificações de índice clusterizado são feitas.
gotqn
3
@gotqn Sim. Off-linha foi o padrão para os velhos tipos LOB text, ntexte image. Você também pode armazenar os tipos grandes em uma tabela separada, é claro.
Paul White 9
4

Esse comportamento para armazenamento de objetos grandes pode ser controlado pela configuração da tabela:

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

A referência na documentação do SQL Server 2012 está em: http://msdn.microsoft.com/en-us/library/ms173530.aspx

Portanto, você pode controlar onde o espaço é usado, em linha ou armazenado fora de linha.

RLF
fonte
Obrigado, eu realmente não sabia que você é capaz de controlar isso.
gotqn