O controle de versão de linha mantém 14 bytes de informações de versão interna para cada linha. Mas isso é realmente um custo por linha ou é um custo que também se aplica a cada índice na tabela?
Parece que os 14 bytes também devem ser adicionados a todos os registros de índice para que as varreduras somente de índice (e outros acessos somente de índice) possam ver as informações de versão e perceber um instantâneo pontual dos dados.
Todas as informações que pude encontrar na web falam apenas sobre uma sobrecarga por linha de 14 bytes.
Por que ele deve ser adicionado a todos os registros de índice ? Você quer dizer todos os índices ou todas as linhas de todos os índices?
Apenas as linhas afetadas dos índices afetados receberão uma tag de 14 bytes.
Aqui estão 3 exemplos.
Suponha que tenhamos uma tabela agrupada de 100 páginas (com
id int PK
) e 1 índice não agrupado nela (em outra colunaCol1
), e alteramos 10 chaves (id
) de índice agrupado.Todas as 10 linhas da tabela clusterizada receberão a tag de versão da linha (10 linhas, não 100 linhas), e as 10 linhas afetadas do índice não clusterizado terão essa tag porque cada índice não clusterizado contém a chave do índice clusterizado pelo menos no nível da folha, portanto, 10 linhas de índice não clusterizado terão suas versões também.
Você pode provar isso para si mesmo alterando 10 linhas na tabela clusterizada com índice não clusterizado em db com
RCSI
e verificandosys.dm_tran_version_store
: haverá 20 linhas e você poderá distinguir linhas de índice clusterizadas de linhas de índice não clusterizadas por seu tamanho................................................... .
Agora suponha que temos a mesma tabela com 100 linhas e índice não clusterizado na mesma
Col1
coluna. Agora fazemos uma colunaupdate
deste heap .id
Se você verificar agora
sys.dm_tran_version_store
, verá apenas 10 linhas, são 10 linhas de um heap, não há nenhuma linha de índice. Isso ocorre porque nosso índice emCol1
não foi alterado quando atualizamos 10id
. Nossoid
, neste caso, não afeta o índice não clusterizado que possui RID como ponteiro de retorno para um heap no nível da folha.É claro que se nosso índice não clusterizado tivesse
id
como campo-chave ou campo incluído,update
ofid
afetaria esse índice também, neste caso, encontramos 20 linhasrow version store
novamente................................................... .
Exemplo N3: tabela com estrutura Col1, Col2, Col3. Índices: ix_1 (Col1), ix_3(Col3).
Atualizamos o Col2 que não é apresentado em nenhum índice. Somente as linhas afetadas da tabela receberão tags de versão de linha, ix_1 e ix_3 não serão afetadas.
Como Solomon Rutzky apontou em seu comentário, essas tags de versão serão apresentadas em índices até
INDEX REBUILD
.Abaixo está a citação deste livro: Pro SQL Server Internals Por Dmitri Korotkevitch