#16 – Para que serve

Fala galera, boa noite.

Último dia do mês de setembro e como costumo dizer o tempo esta passando a cada dia de uma maneira mais rápida que não conseguimos nos deparar com tudo o que acontece ao nosso redor.

São exatamente 22:07 hrs da noite de um sábado que já esta chegando ao fim e com ele o final também de mais um mês de muita luta e trabalho neste ano de 2017, eita ano complicado.

Mas se você esta lendo este post é porque de alguma maneira acabou chegando até aqui, muito obrigado por sua visita, sendo este o post de número 16 da sessão Para que serve, já estava passando da hora de publicar mais um conteúdo exclusivo para esta sessão.

O conteúdo de hoje é um assunto que eu pouco trabalhei em toda minha carreira de DBA, olha que já fazem 17 anos que venho me dedicando diariamente a esta função, mas o recurso que será destacado hoje não é assim “tão velhinho” como eu (kkkkk).

Hoje vou destacar um pouco sobre índices, ai você pode se perguntar, poxa vida você pouco trabalhou com índices, como assim? Pois é, a resposta tão uma pequena perda de verdade, o tipo de índice ao qual eu me refiro pois adicionado ao Microsoft SQL Server a partir da versão 2012, agora acredito que ficou fácil saber de qual índice estou me referindo, se você ainda não se lembrou ou não se atentou para a dica, estou me referindo ao ColumnStore Index. Agora, tenho a certeza que você se lembrou desta nova forma de armazenamento de dados criada pelo time de engenheiros do Microsoft SQL Server a partir da versão 2012 e que ao longo das próximas versões sofreu diversas atualizações e melhorias.

Se a sua resposta é não ou sinceramente você não conhece esta “nova maneira” de trabalhar com índice, não fique preocupado, como de costume vou fazer uma breve introdução sobre este recurso, como também, vamos fazer alguns comparativos em relação a espaço em disco ocupado e custo de processamento em relação aos tradicionais índices Clustered e NonClustered, sendo estes conhecidos como índices Row Store.

Então chegou a hora de conhecer um pouco mais sobre este recurso, desta forma, seja bem vindo ao #16 – Para que serve – Algumas características e comportamentos do ColumnStore Index.

Introdução

Segundo a documentação oficial do Microsoft SQL Server,  índice columnstore é o padrão para armazenar e consultar grandes tabelas de fatos de repositório de dados. 

Um columnstore index é uma tecnologia para armazenamento, recuperação e gerenciamento de dados usando um formato de dados colunar, chamado columnstore.

Ele usa armazenamento de dados baseado em coluna e processamento de consultas para alcançar um desempenho de consulta até 10 vezes melhor no data warehouse em relação ao armazenamento tradicional orientado por linha e até 10 vezes mais compactação de dados em relação ao tamanho dos dados descompactados.

A partir do SQL Server 2016, os índices columnstore permitem a análise operacional, a capacidade de executar análises de alto desempenho em tempo real em uma carga de trabalho transacional. 

ColumnStore Vs RowStore

Um columnstore são dados logicamente organizados como uma tabela com linhas e colunas e fisicamente armazenados em um formato de dados com reconhecimento de coluna.

Um rowstore são dados logicamente organizados como uma tabela com linhas e colunas e fisicamente armazenados em um formato de dados com reconhecimento de linha. No SQL Server, rowstore refere-se à tabela em que o formato de armazenamento de dados subjacente é um heap, um índice clusterizado ou uma tabela com otimização de memória.

Característica 1: Por padrão até a versão 2012 todo e qualquer índice do tipo Clustered e NonClustered ao ser criado era associado ao mesmo uma estrutura de armazenamento de dados utilizando a tecnologia de RowStore, neste caso, ao invés de conter somente a coluna relacionada ao índice o mesmo possuía a linha por completa o que acarretava um aumento considerável de espaço em disco, como também, um custo de processamento maior para o SQL Server quando o dado solicitado era pesquisado.

Seguindo em frente, já sabemos um pouco sobre esta nova maneira de se armazenar dados contidos em um índice, característica muito importante e que pode nos trazer grandes benefícios.

Quais podem ser os outros benefícios ou características nativas existentes no ColumnStore Index que podem nos fazer adotar este tipo de tecnologia? Esta e muitas outras perguntas que eu mesmo sempre fiz em relação á este tipo de índice serão respondidas a seguir, através do ambiente que estaremos utilizando neste post.

Ambiente

Para que possamos entender ainda mais sobre o ColumnStore Index, nada melhor do que colocar em prática este recurso, para tal vamos começar a montar nosso ambiente de teste, composto por três tabelas similares denominadas:

  • MassaDeDadosCompressaoPorRow;
  • MassaDeDadosCompressaoPorPage; e
  • MassaDeDadosCompressaoColumnStore.

Estes três tabelas serão formadas por duas simples colunas denominadas:

  • Record; e
  • Number.

Onde a coluna Record será utilizada como identificar das linhas de registros que estão sendo manipuladas, sendo seu valor preenchido de forma automática através da propriedade Identity().

A coluna Number corresponde ao número que será inserido de forma aleatório neste coluna, esta será a coluna que iremos utilizar para a construção dos respectivos índices em cada tabela.

Vamos então através do Bloco de Código 1 realizar a criação de cada tabela, suas colunas e seus respectivos índices. Vale ressaltar que além de índices nas tabelas MassaDeDadosCompressaoPorRow e MassaDeDadosCompressaoPorPage estamos também utilizando compressão de dados aplicada a linha e compressão de dados aplicada a página de dados respectivamente. 

A seguir apresento o Bloco de Código 1:

— Bloco de Código 1 —

Use TempDB
Go

Create Table dbo.MassaDeDadosCompressaoPorRow
(Record Bigint Identity(1,1),
 Number BigInt
 Index IND_MassaDeDadosCompressaoPorRow Clustered (Number))
WITH (DATA_COMPRESSION = ROW)
Go

Create Table dbo.MassaDeDadosCompressaoPorPage
(Record Bigint Identity(1,1),
 Number BigInt
 Index IND_MassaDeDadosCompressaoPorPage Clustered (Number))
WITH (DATA_COMPRESSION = PAGE)
Go

Create Table dbo.MassaDeDadosCompressaoPorColumnStore
(Record Bigint Identity(1,1),
 Number BigInt,

 INDEX IND_MassaDeDadosCompressaoPorColumnStore Clustered  ColumnStore)
Go

Por enquanto nada de muito inovador ou diferente do que você pode estar acostumado a fazer, mas uma segunda característica do ColumnStore Index pode ser identificada após a criação das tabelas.

Característica 2: Ao realizar a criação de um índice ColumnStore, o Storage Engine mecanismo utilizado pelo Microsoft SQL Server para armazenamento físico de dados, realiza a alocação de um espaço mínimo inicial para armazenar a estrutura base da coluna relacionada ao índice, ou seja, mesmo não possuindo não dado armazenado no ColumnStore um pequeno espaço em disco é ocupado por sua estrutura e respectiva coluna. Para comprovar esta característica utilizamos o Bloco de Código 2 apresentado abaixo:

— Bloco de Código 2 —

Select s.Name As SchemaName, t.Name As TableName, p.rows As RowCounts,
            Cast(Round((Sum(a.used_pages) / 128.00), 2) As Numeric(36,2)) As Used_MB,
             Cast(Round((Sum(a.total_pages) – SUM(a.used_pages)) / 128.00, 2) As Numeric(36, 2)) As Unused_MB,
            Cast(Round((Sum(a.total_pages) / 128.00), 2) As Numeric(36, 2)) As Total_MB
From sys.tables t Inner Join sys.indexes i
                                 On t.OBJECT_ID = i.object_id
                                Inner Join sys.partitions p
                                 On i.object_id = p.OBJECT_ID And i.index_id = p.index_id
                                Inner Join sys.allocation_units a
                                On p.partition_id = a.container_id
                                 Inner Join sys.schemas s
                                 On t.schema_id = s.schema_id
Where t.object_id >1
Group By t.Name, s.Name, p.Rows
Order By s.Name, t.Name
Go 

Agora que você executou o Bloco de Código 2, deve ter obtido como resultado ao similar ao apresentado na Figura 1 a seguir:


Figura 1 – Espaço ocupado pelo ColumnStore Index mesmo são a existência de linhas de registro.

Legal, mas ainda temos algumas coisas para analisar em relação ao ColumnStore Index, nosso próximo passo será realizar o armazenamento de uma massa de dados em cada tabela, aonde estará identificando o tempo de processamento decorrido para inserir um milhão de linhas de registro, valor hoje considerado pouco para se trabalhar com qualquer banco de dados e principalmente para estruturas ColumnStore, mas o suficiente para nossas análises e comparações.

Vamos então trabalhar com o Bloco de Código 3 a seguir:

— Bloco de Código 3 —

— Inserindo 1.000.000 na Tabela MassaDeDadosCompressaoPorRow –|

Declare @Contador Int = 1

While @Contador <=1000000
Begin
Insert Into dbo.MassaDeDadosCompressaoPorRow (Number)
Values (Rand()*1000000000000)

Set @Contador +=1
End
Go

— Inserindo 1.000.000 na Tabela MassaDeDadosCompressaoPorPage —

Declare @Contador Int = 1

While @Contador <=1000000
Begin
Insert Into dbo.MassaDeDadosCompressaoPorPage (Number)
Values (Rand()*1000000000000)

Set @Contador +=1
End
Go

— Inserindo 1.000.000 na Tabela MassaDeDadosCompressaoPorColumnStore —

Declare @Contador Int = 1

While @Contador <=1000000
Begin
Insert Into dbo.MassaDeDadosCompressaoPorColumnStore (Number)
Values (Rand()*1000000000000)

Set @Contador +=1
End
Go

Neste momento nossas tabelas já estão totalmente populadas com 1.000.000 de linhas de registros armazenadas em cada uma delas, vamos então identificar mais duas características presentes no ColumnStore Index, começando pela número 3.

Característica 3: ColumnStore Index apresentam em alguns cenários de armazenamento de dados dependendo do tipo de dados utilizado por ele uma ligeira perda de performance em comparação com o mesmo tipo de dados utilizado em índices que utilizam tecnologia RowStore.

Para comprovar e ajudar a entender esta diferença de comportamento apresento a seguir a Tabela 1 que exibe os dados coletados durante os três processos de inserir realizado pelo Bloco de Código 3 declarado anteriormente.

Tabela Operação Tempo Decorrido
MassaDeDadosCompressaoPorRow Insert 00:00:22
MassaDeDadosCompressaoPorPage Insert 00:00:22
MassaDeDadosCompressaoPorColumnStore Insert 00:00:28

Tabela 1 – Comparativo de tempo decorrido para inserção de 1.000.000 de linhas de registro em cada tabela.

Nossa próxima característica esta relacionada ao espaço físico ocupado em disco para cada índice de acordo com a tecnologia de armazenamento utilizada e a forma de compressão aplicada.

Característica 4: Tabelas que possuem índice do tipo ColumnStore ocupam um espaço físico em disco infinitamente menor que tabelas que possuem índices RowStore, o que representa que o espaço ocupado em disco por índices que utilizam tecnologia ColumnStore podem apresentar uma economia de espaço em disco entre 70 e 90%, algo que devemos considerar em muito quando vamos trabalhar com um volume consideravelmente grande de dados.

A Tabela 2 apresentada abaixo ilustra esta diferença de espaço em disco ocupada por cada tabela:

Dados coletados pelo SP_SpaceUsed
Tabela Linhas Espaço Reservado  Dados Índices Não Utilizado
dbo.MassaDeDadosCompressaoPorRow 1000000 18592 KB 18448 KB 104 KB 40 KB
dbo.MassaDeDadosCompressaoPorPage 1000000 17312 KB 17192 KB 96 KB 24 KB
dbo.MassaDeDadosCompressaoPorColumnStore 1000000 28904 KB 28696 KB 144 KB 64 KB

Tabela 2 – Dados coletados pela System Stored Procedure SP_SpaceUsed.

Observação: Se analisarmos os dados da Tabela 2 podemos notar que a compressão por página de dados para este cenário de 1.000.000 de linhas de registro foi um pouco superior em relação a economia de espaço em disco se comparada com a compressão por linha de dados, essa é uma característica interessante quando trabalhamos com compressão de dados fazendo uma análise de minimal space entre Row Compression e Page Compression.

Uma outra possibilidade para notar esta diferença considerável de espaço alocado, reservado e ocupado fisicamente em disco poderia ser obtido através de uma nova execução do Bloco de Código 2 apresentado anteriormente, para tal a Tabela 3 apresenta o resultado desta nova execução:

Dados coletados através do Bloco de Código 2
Tabela Linhas Espaço Ocupado em MBs Espaço Não Utilizado em MBs Total MBs
MassaDeDadosCompressaoPorRow 1000000 18.12 0.04 18.16
MassaDeDadosCompressaoPorPage 1000000 16.88 0.02 16.91
MassaDeDadosCompressaoPorColumnStore 1000000 0.02 0.05 0.07

Tabela 3 – Dados coletados através da execução do Bloco de Código 2.

Observação: No que diz respeito a minimal space quando trabalhamos com o ColumnStore Index em comparação com Row Compression ou Page Compression a diferença é extremamente assustadora, aonde o ColumnStore Index aplica uma técnica de armazenamento de dados muito interessante que possibilita esta ganho de espaço e consequentemente ganho de performance. Esta técnica é conhecida como Row Group.

Estamos quase no final, vamos agora identificar mais uma importante característica presente em um ColumnStore Index, relacionada a performance algo que este tipo de tecnologia apresenta como principal vantagem e benefícios em relação a índices RowStore ainda mais quando trabalhamos com grandes volumes de dados em ambientes relacionais.

Nossa análise será iniciada através da execução da Bloco de Código 4 declarado abaixo, observe que estaremos habilitando os contadores de estatísticas de processamento relacionados a Tempo e Input/Output denominados:

Através do uso destes contadores o Management Studio ira nos retornar na guia de mensagens um conjunto de dados relacionados ao tempo de processamento, quantidade de leituras lógicas e físicas demandadas por cada transação que estaremos processando, com base, nestes e outros dados poderemos identificar quando será o diferença do ColumnStore Index em comparação com os outros índices existentes em nossas tabelas.

Outro elemento importante que estaremos utilizando, consiste na quantidade de linhas pesquisadas em cada tabela, você poderá notar que para cada Select declarado no Bloco de Código 4 estaremos filtrando e limitando nosso result set na faixa de valores existentes entre as linhas de registro 525.000 e 789.000.

Vamos então executar o Bloco de Código 4, recomendo que faça a execução de cada select de forma separada, anote os dados retornados pelos contadores Time e IO:

— Bloco de Código 4 —

Set Statistics Time On
Set Statistics IO On
Go

Select * from dbo.MassaDeDadosCompressaoPorRow
Where Record Between 525000 And 789000
Go

Select * from dbo.MassaDeDadosCompressaoPorPage
Where Record Between 525000 And 789000
Go

Select * from dbo.MassaDeDadosCompressaoPorColumnStore
Where Record Between 525000 And 789000
Go

Set Statistics Time Off
Set Statistics IO Off
Go

Ufa, estamos quase lá, nosso Bloco de Código 4 foi apresentado, tenho a certeza que você executou cada Select de forma individual, anotando os respectivos valores de tempo de processamento e input/output retornados pelo SQL Server, muito bem, agora vamos analisar a Tabela 4 apresentada abaixo e identificar o comportamento apresentado pelo ColumnStore Index.

Tabela Operação Tempo Decorrido CPU Time Elapsed Time Scan Count Logical Reads Physical Reads
MassaDeDadosCompressaoPorRow Select 00:00:02 110 ms 769 ms 1 2316 0
MassaDeDadosCompressaoPorPage Select 00:00:02 203 ms 830 ms 1 2158 0
MassaDeDadosCompressaoPorColumnStore Select 00:00:01 125 ms 911 ms 2 3599 0

Tabela 4 – Conjunto de dados coletados e apresentados pelos contadores TIME e IO durante a execução dos selects declarados no Bloco de Código 4.

Característica 5: Índice do tipo ColumnStore sempre serão mais rápidos que índice RowStore mesmo apresentando alguns dados que valores superiores, dentre eles: Scan Count e Logical Reads.

Analisando os dados apresentados anteriormente na Tabela 4, fica mais fácil observar alguns comportamentos presentes em índices ColumnStore, nos quais a quantidade de leituras lógicas pode estar mais presente neste tipo de índice devido justamente a sua forma de armazenamento de dados, além disso, o número de contagem de varreduras conhecidos como Scan Count, outro fator que também esta relacionado ao armazenamento do dados no índice na forma de coluna ao invés de linha como no RowStore.

Mas o elemento mais importante esta vinculado ao tempo decorrido na busca dos dados solicitados, tanto a tabela MassaDeDadosCompressaoPorRow como também a MassaDeDadosCompressaoPorPage demandaram 00:00:02 segundos para identificar, filtrar e apresentar 264.001 mil linhas de registro.

Nesta mesma comparação, os dados pesquisados na tabela MassaDeDadosCompressaoPorRow foram retornados em tela em 00:00:01 segundo, ou seja, uma ligeira diferença no tempo de processamento, o que pode parecer muito insignificante para o atual volume de dados que estamos trabalhando, mas imagine este ganho de processamento quando estivermos manipulando bilhões, trilhões ou quatrilhões de linhas de dados, mesmo que o elapsed time do processamento tenha sido um pouco maior que os demais. 

Desta forma, os dados apresentados na Tabela 4 em conjunto com os demais dados presentes em cada análise realizada neste post, nos traz a seguinte certeza, que índices ColumnStore podem e devem ser analisados, o que nos permite também dizer que o uso deste tipo de tecnologia poderá ser de grande avaliar e benefícios no que se relaciona a armazenamento e processamento de dados.

Com isso chegamos ao final deste post, olha foi surpreende e desafiador….


Referências

https://docs.microsoft.com/en-us/sql/relational-databases/data-compression/row-compression-implementation

https://docs.microsoft.com/en-us/sql/relational-databases/data-compression/page-compression-implementation

https://docs.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property

https://docs.microsoft.com/en-us/sql/relational-databases/data-compression/data-compression

https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-spaceused-transact-sql

https://docs.microsoft.com/en-us/sql/relational-databases/indexes/columnstore-indexes-overview

https://docs.microsoft.com/en-us/sql/t-sql/statements/set-statistics-time-transact-sql

https://docs.microsoft.com/en-us/sql/t-sql/statements/set-statistics-io-transact-sql

https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-tables-transact-sql

https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-indexes-transact-sql

https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-partitions-transact-sql

https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-allocation-units-transact-sql

https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/schemas-catalog-views-sys-schemas

Links

Caso você ainda não tenha acessado os posts anteriores desta sessão, fique tranquilo é fácil e rápido, basta selecionar um dos links apresentados a seguir:

https://pedrogalvaojunior.wordpress.com/2017/06/28/15-para-que-serve/

https://pedrogalvaojunior.wordpress.com/2017/04/30/14-para-que-serve/

https://pedrogalvaojunior.wordpress.com/2017/03/25/13-para-que-serve/

https://pedrogalvaojunior.wordpress.com/2017/01/23/12-para-que-serve/

Conclusão

Identificar a melhor forma de armazenar nossos dados em um Sistema Gerenciador de Banco de Dados não é um tarefa das mais fáceis e comum de se realizada, escolher qual tecnologia de armazenamento visando economia de espaço e performance muito menos.

A partir da versão 2012 do Microsoft SQL Server esta tarefa começou a ficar um pouco mais interessante e amigável com a adoção da tecnologia de armazenamento de dados existentes em um índice no formato de coluna ao invés de linha, tecnologia conhecida e denominada como ColumnStore Index.

O uso do ColumnStore Index deve ser avaliado, sua principal característica relaciona-se ao capacidade de processamento de um grande volume de dados com baixo custo de tempo, mesmo em ambientes relacionais, o que nos permite dizer que utilizar um índice ColumnStore poderá lhe trazer benefícios tanto no espaço ocupado em disco, bem como, no tempo de processamento na pesquisa de dados.

Agradecimentos

Antes de finalizar, são 00:46hrs da madrugada, já estamos no dia 01/10, ou seja, um novo mês esta começando neste domínio.

Chegou a hora do descanso, se preparar para um novo dia que daqui a pouco estará raiando, espero que você possa fazer o mesmo, aproveitar o seu dia ainda mais um domingo, tentar viver um pouco sem se preocupar com os problemas.

Mais uma vez obrigado por sua ilustre visita, sinto-me honrado com sua presença, espero que este conteúdo possa lhe ajudar e ser útil em suas atividades profissionais e acadêmicas.

Um forte abraço, até o próximo post da sessão Para que serve…..

Valeu.

Anúncios

Sobre Junior Galvão - MVP

Profissional com vasta experiência na área de Tecnologia da Informação e soluções Microsoft. Graduado no Curso Superior em Gestão da Tecnologia de Sistemas de Informação. Pós-Graduado no Curso de Gestão e Engenharia de Processos para Desenvolvimento de Software com RUP na Faculdade FIAP - Faculdade de Informática e Administração Paulista de São Paulo. Pós-Graduado em Gestão da Tecnologia da Informação Faculdade - ESAMC Sorocaba. Formação MCDBA Microsoft, autor de artigos acadêmicos e profissionais postados em Revistas, Instituições de Ensino e WebSistes. Meu primeiro contato com tecnologia ocorreu em 1995 após meus pais comprarem nosso primeiro computador, ano em que as portas para este fantástico mundo se abriram. Neste mesmo ano, comecei o de Processamento de Dados, naquele momento a palavra TI não existia, na verdade a Tecnologia da Informação era conhecida como Computação ou Informática, foi assim que tudo começou e desde então não parei mais, continuando nesta longa estrada até hoje. Desde 2001 tenho atuado como Database Administrator - Administrador de Banco de Dados - SQL Server em tarefas de Administração, Gerenciamento, Migração de Servidores e Bancos de Dados, Estratégias de Backup/Restauração, Replicação, LogShipping, Implantação de ERPs que utilizam bancos SQL Server, Desenvolvimento de Funções, Stored Procedure, Triggers. Experiência na Coordenação de Projetos de Alta Disponibilidade de Dados, utilizando Database Mirroring, Replicação Transacional e Merge, Log Shipping. Atualmente trabalho como Administrador de Banco de Dados no FIT - Instituto de Tecnologia da Flextronics, como também, Consultor em Projetos de Tunnig e Performance para clientes, bem como, Professor Titular na Fatec São Roque. Desde 2008 exerço a função de Professor Universitário, para as disciplinas de Banco de Dados, Administração, Modelagem de Banco de Dados, Programação em Banco de Dados, Sistemas Operacionais, Análise e Projetos de Sistemas, entre outras. Possuo titulações e Reconhecimentos: Microsoft MVP, MCC, MSTC e MIE.
Esse post foi publicado em Azure, Banco de Dados, Banco de Dados, Curiosidades, DBA, Desenvolvimento, Dicas, Diversos, Educação, Ferramentas, Hardware, Inovações, Interoperabilidade, Linux, Microsoft, MSDN, Mundo SQL Server, Notícias, Para que serve, Sistema Operacional, SQL Server, TechNet, TI Verde, Transact-SQL, Utilitários, VIRTUAL PASS BR, Virtualização, Visual Studio, Visual Studio, Windows, Windows Core, Windows Server e marcado , , , , , , , , , , , , , , , , , , , , , , , , . Guardar link permanente.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s