Dica do Mês – Utilizando a Trace Flag 9292 para exibir objetos estatísticos úteis


 

Olá comunidade, boa tarde.

Tudo bem? Estamos se aproximando dos últimos dias de férias ou recesso para grande maioria dos professores e profissionais de educação espalhados por todo Brasil. E ai, já esta preparado para voltar a luta? Posso dizer tranquilamente que sim, eu estou pronto para voltar a conviver com meus alunos e amigos de trabalho.

Antes de começarmos a falar sobre o post de hoje, nada mais justo começar agradecendo como de costume a você está aqui neste momento acessando meu blog. Espero que possa ter encontrado o que precisa, bem como, esteja gostando do conteúdo publicado, fique a vontade para entrar em contato expressando suas opiniões e demais pensamentos.

Neste novo post da sessão Dica do Mês, vou apresentar um recurso que imagino ser conhecido por muitos ou principalmente pelos profissionais de banco de dados, estou me referindo as Trace Flag ou sinalizador de rastreamento em português.

Você já ouvir falar sobre isso ou já utilizou? Eu imagino que sim pois aqui no meu blog diversos posts e artigos foram publicado ao longo dos últimos anos sobre este tipo de recurso. Hoje mais especificamente vou destacar o uso da Trace Flag 9292, por acaso você já utilizou em algum momento esta trace flag?

Bom independente da sua reposta vamos conhecer um pouco mais sobre ela, sua forma de uso e como poderá nos ajudar a entender ainda mais o funcionamento das estatísticas e seus chamados objetos úteis para análise do plano de execução.

E ai esta curioso para saber um pouco sobre este recurso? Eu estou, sendo assim, vamos em frente, seja bem vindo ao post Dica do Mês – Utilizando a Trace Flag 9292 para exibir objetos estatísticos úteis.

Vamos em frente…..


Introdução

Todos sabemos que as estatísticas desempenham um papel muito importante dentro do SQL Server, como também, sabemos que as estatísticas são usadas pelo otimizador de consultas para gerar o plano de execução para cada consulta.
Então a questão é, podemos verificar qual objeto estatístico é útil para a execução da consulta? Sim, usando o Trace Flag do SQL Server 9292. Este é um do sinalizador de rastreamento que pode ser usado durante a solução de problemas.
Esse sinalizador de rastreamento é usado para obter o relatório sobre objetos de estatísticas considerados como “interessantes” ou “úteis” pelo otimizador de consulta durante a compilação ou recompilação de consulta.

Adicionada ao Microsoft SQL Server 2008 após a instalação do service pack 1 e mantida até as atuais versões, no momento em tomamos a decisão de utilizar a Trace Flag 9292, orientamos o SQL Server a apresentar todos os objetos estatísticos considerados úteis por parte do plano de execução para realizar o processamento e retorno dos dados.

O uso da Trace Flag 9292 dentro de uma sessão ou query específica, nos ajuda a entender e conhecer como as estatísticas e seus elementos podem mudar totalmente a maneira que o plano de execução é idealizado, armazenado e processado.

Através dela podemos obter um relatório sobre as estatíticas para cada objeto envolvido em nossa query, onde estes supostos objetos devem ser considerados úteis, ou melhor dizendo válidos e aplicáveis no decorrer do caminho realizado até a apresentação do resultado.

Esta é uma trace flag que pode ser usada durante a resolução de problemas, onde sua função é apresentar na guia de mensagens do Management Studio, um pequeno cabeçalho contendo informações estatísticas sobre cada componente útil e válido para formas os dados estatísticos de processamento da query. Este cabeçalho é conhecido como Stats header loaded.

Para ativar a trace flag utilize o comando DBCC TraceON (9292) ou DBCC TraceOFF (9292) para desativar, ou se preferir utilize a opção QueryTraceOn em sua respectiva query.

Agora que já conhecemos um pouco mais sobre os conceitos desta trace flag, chegou a hora de colocar as mãos no teclado e conhecer melhor o funcionamento da flag 9292 e de que forma ela poderá impactar o trabalho do Microsoft SQL Server, nos permitindo identificar os objetos úteis processados ou candidatos a processamento por parte do Query Processor em conjunto com Execution Plan.

Preparando o ambiente

Nosso ambiente será bastante simples, basicamente criaremos um banco de dados denominado DBTrace9292, constituído de uma tabela denominada TBTrace9292, para tal utilizaremos o Bloco de Código 1 que apresenta a criação dos respectivos objetos:

— Bloco de Código 1 —
— Criando o Banco de Dados DBTrace9292 —
Create Database DBTrace9292
Go

— Acessando —
Use DBTrace9292
Go

— Criando a Tabela TBTrace9292 —
Create Table TBTrace9292
(Codigo Int Identity(1,1) Primary Key,
Valores Int,
Descricao Varchar(100))
Go

Após a criação dos objetos básicos, nosso próximo passo será a criação de índice nonclustered para coluna Valores que nos permitirá fazer o uso de estatísticas de processamento para esta coluna durante o processo de inserção de dados, conforme apresenta o Bloco de Código 2 apresentado abaixo:

— Bloco de Código 2 —
— Criando o Índice NonClustered IND_TBTrace9292Valores —
Create NonClustered Index IND_TBTrace9292Valores on TBTrace9292(Valores)
Go

— Inserindo uma linha de registro na Tabela TBTrace9292 —
Insert Into TBTrace9292
Values(2000,’pedrogalvaojunior.wordpress.com’)
Go

— Inserindo 1.000 linhas de registros na Tabela TBTrace9292 —
Insert Into TBTrace9292
Values(4000,’pedrogalvaojunior.wordpress.com’)
Go 1000

Note que existir uma pequena mais importante diferença entre os dois Inserts, no primeiro estamos inserindo uma linha de registro na tabela TBTrace9292. No segundo criamos em tempo de execução um pequeno bloco de inserção de linhas, sendo este processado 1.000 vezes, inserindo então 1.000 linhas.

Seguindo em frente, o Bloco de Código 3 será utilizado para criarmos uma Stored Procedure denominada P_PesquisarValores como forma para buscar os respectivos registros armazenados na tabela TBTrace9292. A seguir apresento o Bloco de Código 3:

— Bloco de Código 3 –
— Criando a Stored Procedure P_PesquisarValores —
Create Procedure P_PesquisarValores @Valor int
As
Begin
Select Descricao from TBTrace9292
Where Valores = @Valor
OPTION (RECOMPILE)
End
Go

Se você for como eu, normalmente gosto de fazer uma análise de código antes de colocar em prática no meu ambiente, sendo assim, vamos lá. Analisando de forma superficial a Stored Procedure P_PesquisarValores a princípio não apresenta nada muito especial ou de grande complexidade em seu código, mas sim o uso de opção Recompile que justamente vai orientar o plano de execução a recompilar a  P_PesquisarValores no momento da sua execução, forçando assim que a cada execução um novo plano de execução seja criado em conjunto com uma nova análise estatística e seus demais elementos.

O próximo passo consiste na pesquisa de um dos valores armazenados na tabela TBTrace9292 através da execução e processamento da Stored Procedure P_PesquisarValores. Para este passo vamos utilizar o Bloco de Código 4 a seguir, antes de sua execução recomendo habilitar a apresentação do Plano de Execução Atual no SQL Server Management Studio através do botão Include Actual Execution Plan ou simplesmente através da tecla de atalho CTRL+M.

— Bloco de Código 4 —
— Habilitando as TraceFlags 9292 e 3604 —
DBCC TraceOn(9292,3604,-1)
Go

Dica: Utilize o comando DBCC TraceStatus WITH NO_INFOMSGS para verificar quais Trace Flags estão habilitadas em qual nível de escopo.

— Execuntando a Stored Procedure P_PesquisarValores —
Exec P_PesquisarValores 4000
Go

Pois bem, após a execução do Bloco de Código 4, o Microsoft SQL Server realizou o processamento da nossa Stored Procedure P_PesquisarValores realizando uma busca de todas as linhas de registros que possuem o valor 4.000, onde obrigatoriamente foram retornadas 1.000 linhas de registros.

Até ai nada de novo ou surpreende, o que justamente eu quero mostrar para vocês é o que o Management Studio apresenta na guia Messages após o processamento do Bloco de Código 4, conforme apresenta a Figura 1 abaixo:

Note que o cabeçalho retornado pela Trace Flag 9292 conhecido como Stats header loaded esta apresentando os objetos realmente utilizados para o processamento de nossa query, bem como, os objetos considerados úteis e necessários para criação, compilação e processamento do plano de execução envolvidos na execução, sendo eles:

  • Database: DBTrace9292;
  • Table: TBTrace9292,
  • Index: IND_TBTrace9292Valores, sendo este do tipo Nonclustered;
  • Column: Valores; e
  • EmptyTable: False, representa que a tabela possui linhas de registro.

Perfeito, perfeito, ai esta a prova que a Trace Flag 9292 nos permite identificar de forma simples, coerente e muito intuitiva todos os objetos envolvidos na execução de uma query, stored procedure ou demais elementos que permitem a criação de um plano de execução.

Desta forma, chegamos ao final de mais um post, tendo a sensação de dever cumprido, espero que você tenha gostado, como sempre o Microsoft SQL Server nos surpreende com a sua capacidade e potencialidade de recursos.


Referências

https://thomaslarock.com/2016/06/sql-server-Trace-flags/

https://pedrogalvaojunior.wordpress.com/2016/02/26/02-para-que-serve/

DBCC TRACEOFF (Transact-SQL)

DBCC TRACEON (Transact-SQL)

DBCC TRACESTATUS (Transact-SQL)

EXECUTE (Transact-SQL)

Query Hints (Transact-SQL)

Post Anteriores

https://pedrogalvaojunior.wordpress.com/2017/05/23/conhecendo-e-aplicando-o-uso-de-atualizacao-de-estatisticas-incrementais/

https://pedrogalvaojunior.wordpress.com/2017/04/13/dica-do-mes-microsoft-sql-server-identificando-as-transacoes-que-estao-utilizando-o-transact-log/

https://pedrogalvaojunior.wordpress.com/2017/03/01/dica-do-mes-microsoft-sql-server-2016-sp1-novo-argumento-use-hint-disponivel-para-query-hints/

https://pedrogalvaojunior.wordpress.com/2017/01/16/dica-do-mes-conhecendo-a-nova-dmf-sys-dm_exec_input_buffer-no-microsoft-sql-server-2016/

https://pedrogalvaojunior.wordpress.com/2016/11/28/dica-do-mes-sql-server-2016-sp1-comando-create-or-alter/

https://pedrogalvaojunior.wordpress.com/2016/10/24/dica-do-mes-sql-server-2016-obtendo-informacoes-sobre-o-cache-de-execucao-de-funcoes/

Conclusão

Muitas vezes temos dificuldade em entender como um determinado recurso ou funcionalidade esta sendo utilizada pelo Microsoft SQL Server, com também, de que maneira este elemento poderá impactar nosso ambiente.

Neste post foi possível apresentar como a Trace Flag 9292 nos permite identificar quais objetos estão sendo utilizando durante o processamento e execução de uma determinada query. Um recurso de fácil configuração tanto para ser ativado como também desativado a qualquer momento ou necessidade.

Recomendo que você realize diversos testes e validações antes de fazer qualquer tipo de uso de uma trace flag em seu ambiente de produção, isso também se aplica a Trace Flag 9292.

Agradecimentos

Mais uma vez obrigado por sua visita, agradeço sua atenção, fique a vontade para enviar suas críticas, sugestões, observações e comentários.

Um forte abraço, nos encontramos em breve com mais um post da sessão Dica do Mês.

Valeu….

#08 – Para que serve


Boa noite comunidade, boa noite amantes do SQL Server e Banco de Dados…..

Hoje dia 03 de Setembro começo de noite de mais um sabádão, estamos vivendo os primeiros dias de mais um mês e se aproximando do final de 2016. Antes de começar a falar sobre o post de hoje, gostaria de compartilhar mais algumas conquistas obtidas neste últimos dias, bem como uma outra que esta por vir.

Há primeira conquista se refere aos meus alunos do Curso de Sistemas de Informação para Internet da Fatec São Roque, tive o imenso prazer em poder lecionar para esta fantástica turma nos últimos 4 semestre, desejo a vocês tudo de bom, felicidades e muitas conquistas.

A próxima ainda mais importante é o aniversário do meu filho mais velho Eduardo Galvão que no próximo dia 06 de Setembro estará completando 15 anos de vida, com certeza um dos momentos mais felizes e esplêndidos da minha vida. Desejo a você meu pequeno grande menino um futuro fantástico, muito saúde, felicidades e alegrias.

Vamos em frente, voltando ao post de hoje da sessão Para que serve, conforme prometido vou dar continuidade ao post anterior onde começamos a conhecer um pouco sobre o conceito de Índice Hipotéticos. Caso você não tenha acessado o post anterior não perca tempo clique no link acima e conheça um pouco sobre este conceito tão surpreende quando a sua forma de uso.


Começa agora o #08 – Para que serve – Índices Hipotéticos – Parte II.

No #08 – Para que serve, daremos início ao processo de criação do nosso ambiente de banco de dados com objetivo de construir um estrutura específica para conhecermos e simularmos o uso dos índices hipotéticos. É isso siga-me os bons, mãos no teclado, acompanhe a sequência de passos apresentandos abaixo:

— Passo 1 – Criando o Banco de Dados HypotheticalDB —

CREATE DATABASE [HypotheticalDB]
ON  PRIMARY
(NAME = ‘HypotheticalDB-Data’,
 FILENAME = ‘C:\SQLServer2016\Data\HypotheticalDB_Data.mdf’ ,
 SIZE = 4MB ,
 MAXSIZE = 4096MB,
 FILEGROWTH = 2MB )
LOG ON
(NAME = ‘HypotheticalDB-Log’,
 FILENAME = ‘C:\SQLServer2016\Log\HypotheticalDB_Log.ldf’ ,
 SIZE = 8MB ,
 MAXSIZE = 2GB ,
 FILEGROWTH = 4MB)
GO

— Passo 2 – Acessando o Banco de Dados —
Use HypotheticalDB
Go
— Passo 3 – Criando as Tabelas —
Drop Table If Exists dbo.Clientes
CREATE TABLE Clientes
(Codigo  INT Identity(1,1) NOT NULL Primary Key Clustered,
 CodigoCategoria TinyInt NOT NULL,
 Nome  VARCHAR(60) NOT NULL,
 Endereco VARCHAR(80) NOT NULL,
 Estado  CHAR(2) NOT NULL,
 DataUltimaCompra  DATETIME)
Go
Drop Table If Exists dbo.ClientesCategorias
CREATE TABLE ClientesCategorias
(Codigo TinyInt NOT NULL,
 Descricao VARCHAR(20) NOT NULL)
Go

Nota: Observe que no passo 3 estamos utilizando uma nova instrução introduzida no Microsoft SQL Server 2016, estou me referindo ao Drop If Exists uma das mais esperadas melhorias a serem adicionados ao Microsoft SQL Server que por muitos anos estava sendo aguardada.

— Passo 4 – Inserindo dados na Tabela ClientesCategorias —
INSERT Into ClientesCategorias (Codigo, Descricao)
 Values (1, ‘Premier’),
             (2, ‘Advanced’),
             (3, ‘Special’)
Go
— Passo 5 – Inserindo dados na Tabela Clientes —
Insert Into Clientes (CodigoCategoria, Nome, Endereco, Estado, DataUltimaCompra)
Values (3, ‘José Bonito’,’Rua A’,’SP’,GETDATE()-30),
            (1, ‘Dassaev Silva’,’Rua B’,’SP’,GETDATE()-120),
            (3, ‘Viewer Partes’,’Rua 123′,’RJ’,GETDATE()-720),
            (1, ‘Dino Silva Sauros’,’Avenida Parque dos Dinassauros’,’AM’,GETDATE()-240),
            (2, ‘Fernandino Campos Boyd’,’Estrada Velha’,’MG’,GETDATE()-5),
            (1, ‘Katrina Tornado’,’Rua Storm’,’RG’,GETDATE()-300),
            (2, ‘Washington Wizard’,’Place 1′,’PR’,GETDATE()-1024),
            (3, ‘Chicago Bulls’,’Place 2′,’PR’,GETDATE()-89),
            (2, ‘Denver Nuggets’,’Place 3′,’PR’,GETDATE()-289),
            (2, ‘Los Angeles Lakers’,’Place 4′,’PR’,GETDATE()-390)
Go
— Passo 6 – Consultando os dados —
Select Codigo, Descricao From ClientesCategorias
Go
Select Codigo, CodigoCategoria, Nome, Endereco, Estado, DataUltimaCompra From Clientes
Go
Até aqui nada muito diferente do que normalmente utilizamos em nosso dia-á-dia, talvez o uso da Drop If Exists possa ser um diferencial. Dando continuidade os dois próximos passos serão de extrema importância para nosso ambiente, estaremos justamente realizando a criação de três índices:
  • IND_ClientesCategorias_NaoClusterizado_CodigoSemEstatisticas;
  • IND_ClientesCategorias_NaoClusterizado_CodigoComEstatisticas; e
  • IND_ClientesCategorias_Clusterizado_CodigoComEstatisticas.

Observe que serão criados dois índices não-clusterizados e um índice clusterizado, todos vinculados a tabela ClientesCategorias para coluna Codigo, onde você vai poder notar que dois índices devem ser criados sem estatísticas o que indica para o SQL Server que este será um índice hipotético existindo somente de maneira lógica e não terá nenhum tipo de vínculo ou estrutura física criada. Então siga em frente, mãos no teclado, a seguir os passos 7 e 8:

— Passo 7 – Criando índices hipotéticos não-clusterizado na tabela ClientesCategorias —
CREATE INDEX IND_ClientesCategorias_NaoClusterizado_CodigoSemEstatisticas
 ON ClientesCategorias (Codigo) With Statistics_Only = 0
CREATE INDEX IND_ClientesCategorias_NaoClusterizado_CodigoComEstatisticas
 ON ClientesCategorias (Codigo) With Statistics_Only = -1
Go
— Passo 8 – Criando índices hipotéticos clusterizado na tabela ClientesCategorias —
CREATE CLUSTERED INDEX IND_ClientesCategorias_Clusterizado_CodigoComEstatisticas
 ON ClientesCategorias (Codigo) With Statistics_Only = -1
Go
Antes de continuarmos vou apresentar a Figura 1 que ilustra a criação destes índices dentro da estrutura da tabela ClientesCategorias, você vai poder notar na figura que somente existe estatísticas para estes objetos as guias Keys e Indexes estão vazias:
HypotheticalIndex

Figura 1 – Estrutura da Tabela ClientesCategorias.

Vamos que vamos estamos quase lá, falta pouco, agora vamos executar o passo 9 em duas etapas a primeira será a execução do system stored procedure sp_helpindex responsável em apresentar a estrutura de índices existente em uma determinada tabela, neste caso estou me referindo a tabela ClientesCategorias, sendo assim, vamos realizar esta execução:

 

— Passo 9 – Obtendo informações sobre os índices —
Exec sp_helpindex ClientesCategorias
Go

Após a execução o Management Studio vai retornar nossos três índices criados anteriormente, podemos observar a existência de uma coluna chamada index_description, verifique que todos os índices apresentam a seguinte informação: nonclustered, hypothetical

Você pode estar se perguntando, mas nos não criamos um índice clusterizado? A resposta seria sim, criamos ele continua sendo clusterizado, mas como este não apresenta um estrutura física o mesmo é reconhecido e tratado pelo SQL Server como índice não-clusterizado neste momento, a Figura 2 apresentada este resultado:

HypotheticalIndex2

Figura 2 – Relação de índices hipotéticos pertencentes a table ClientesCategorias.

O próximo passo e realizar a segunda parte do passo 9,  onde faremos a execução do comando DBCC Show_Statistics responsável em apresentar informações sobre as estruturas físicas e lógicas vinculadas a estatísticas de um índice, no nosso caso vamos utilizar os índices:

  • IND_ClientesCategorias_NaoClusterizado_CodigoSemEstatisticas; e
  • IND_ClientesCategorias_NaoClusterizado_CodigoComEstatisticas.

Vamos então executar o bloco de código abaixo:

DBCC SHOW_STATISTICS (ClientesCategorias, IND_ClientesCategorias_NaoClusterizado_CodigoSemEstatisticas)

DBCC SHOW_STATISTICS (ClientesCategorias, IND_ClientesCategorias_NaoClusterizado_CodigoComEstatisticas)
Go

Observando  a Figura 3 a seguir fica mais fácil  entender que o índice: IND_ClientesCategorias_NaoClusterizado_CodigoSemEstatisticas não apresenta nenhuma informação relacionada a estatísticas, ao contrário do índice:

IND_ClientesCategorias_NaoClusterizado_CodigoComEstatisticas, onde o SQL Server após o procedimento de crição do mesmo já estabeleceu alguns dados estatísticos que posteriormente será utilizados no processamento das querys de acordo com sua necessidade. Segui a seguir a Figura 3:

HypotheticalIndex3

Figura 3 – Comparativo entre as estruturas dos índices IND_ClientesCategorias_NaoClusterizado_CodigoSemEstatisticas  e IND_ClientesCategorias_NaoClusterizado_CodigoComEstatisticas.

Falta pouco, pouco mesmo, prometo que estamos no final, vamos executar o passo de número 10, onde estaremos obtendo as informações sobre nossos índices através da catalog view sys.sysindexes, onde nosso índice IND_ClientesCategorias_Clusterizado_CodigoComEstatisticas agora será apresentado como um índice clusterizado, isso nos faz entender que em alguns momentos o SQL Server acaba mudando um pouco o seu comportamento de acordo com a forma de obtenção de informações sobre as estruturas de nossos índices, sinceramente não saberia dizer se isso pode ser considerado uma falha ou até mesmo um possível bug.

Pisando fundo em nosso “acelerador” execute o passo 10 apresenta logo a seguir:

— Passo 10 – Obtendo informações sobre a relação de índices —

SELECT object_id,
             OBJECT_NAME(object_id) AS ‘Tabelas’ ,
             name As ‘Nome do Índice’,
             type_desc,
             is_hypothetical As ‘Índice Hipotético = 1 Não-Hipotético=0’
FROM sys.indexes
WHERE object_id in (object_id(‘ClientesCategorias’), object_id(‘Clientes’))
Go

E agora o tão esperado momento, vamos realmente fazer uso de nossos índices hipotéticos através da execução dos passos 11 e 12 teremos a capacidade técnica de entender o comportamento do SQL Server, principalmente através da comparação dos planos de execução gerados para cada query processada, sendo assim, vamos começar executando o passo 11 a seguir:

— Passo 11 – Executando o Select de maneira clássica sem a diretiva SET AUTOPILOT —
SET SHOWPLAN_XML ON
Go
Select C.Codigo,
          Cc.Codigo As ‘Categoria do Cliente’,
    C.Nome,
    C.Endereco,
    C.Estado,
    C.DataUltimaCompra
From Clientes C Inner Join ClientesCategorias CC
                           On C.CodigoCategoria = CC.Codigo
Where C.Estado = ‘SP’
GO
SET SHOWPLAN_XML OFF
Go
Observe que solicitamos ao Management Studio para realizar o plano de execução da nossa query através da diretiva SET SHOWPLAN_XML, onde o mesmo deverá ser gerado no formato XML, recomendo que você salve este plano de execução para que possamos fazer uso do mesmo no último. Agora execute o passo 12, salve o plano de execução gerado em xml e apresentado de forma gráfica.
— Passo 12 – Executando o Select de maneira personalizada ativando a diretiva SET AUTOPILOT  —
SET AUTOPILOT ON — Ativando a diretiva —
Go
Select C.Codigo,
          Cc.Codigo As ‘Categoria do Cliente’,
    C.Nome,
    C.Endereco,
    C.Estado,
    C.DataUltimaCompra
From Clientes C Inner Join ClientesCategorias CC
                           On C.CodigoCategoria = CC.Codigo
Where C.Estado = ‘SP’
Go
SET AUTOPILOT OFF — Desativando a diretiva —
GO
Muito bem, conseguimos executar nossos dois selects, espero que você tenha salvado os respectivos planos de execução, agora após a execução do passo 12 você deverá esta visualizando o plano de execução deste select, clique com o botão da direita na parte branca e escolha a opção Comparative ShowPlan, selecione o arquivo que representa o plano de execução criado após a execução do passo 11 em seguida o mesmo deverá ser aberto, conforme a Figura 4 a seguir apresenta:
HypotheticalIndex4
Figura 4 – Comparação entre os planos de execução gerados durante a execução dos passos 11 e 12.
Podemos observar que os dois planos de execução são praticamentes idênticos de maneira geral, mas se realmente analisarmos cada um dos operadores, será possível notar um uma pequena diferença no operador Select, onde a instrução CompileMemory nos mostra uma diferença de 8(oito) compilações a menos realizada no passo 11 em comparação com o passo 12, conforme ilustra a Figura 5 abaixo:
HypotheticalIndex5
Figura 5 – Comparativo de resultados apresentados na instrução CompileMemory.
Poxa vida, analisando friamente esta é uma diferença tão pequena que talvez não seja necessário se preocupar ou até mesmo querer entender o que pode ter acontecido. Mas DBA que é DBA de verdade não gosta de se deparar com estas situações em seu ambiente, menos ficar sem uma possível resposta, por mais que muitas vezes ela até mesmo não exista.
Então se você quiser realmente saber o que pode ter influenciado o SQL Server mais especificamente o Database Engine e seus componentes dentre eles o Query Optimizer e o Execution Plan a apresentar este resultado não deixe de acessar o próximo post dedicado aos índices hipotéticos, então nos vemos no #09 Para que serve.
Até lá………..

É isso ai galera, chegamos ao final de mais post da sessão Para que serve!

Espero que você tenha gostado, que as informações compartilhadas aqui possam lhe ajudar a se tornar cada vez um profissional de banco de dados reconhecido e valorizado, um dos papéis na área de tecnologia mais importantes para qualquer empresa.

Reconher o verdadeiro papel de um DBA dentro de sua estrutura, é reconhecer o verdadeiro valor de seus dados e como eles podem se tornar uma infomação valiosa para sua tomada de decisão.

Caso deseje acessar os posts anteriores desta sessão, utilize os links listados abaixo:

#07 – Para que serve


Boa tarde comunidade, boa tarde Brasil!!!!

Começando mais uma tarde de sábado, neste primeiro final de semana do mês de agosto, clima olímpico e muito feliz em ver que o Brasil foi capaz de fazer uma linda festa ontem na abertura dos Jogos Olímpicos Rio 2016, desejo muito sucesso para todos os participantes principalmente aos atletas brasileiros.

O post dedicado a sessão Para que serve deste mês, também esta no clima olímpico, você pode estar se perguntando o porque eu destaquei na minha abertura este clima. Quando estamos pensando em esporte muitas vezes pensamos que não existem possibilidades ou possíveis situações de um determinado time ou atleta ser superado por outro mais fraco, pode ser definido como algo “Hipotético”, sim “Hipotético” na sua definição com base em diversos dicionários: fictício, figurado, imaginário, suposto. Na área de banco de dados isso também pode ser aplicado, principalmente no SQL Server.

Mas de que maneira podemos pensar em algo hipotético, fictício ou imaginário quando estamos trabalhando com banco de dados? Pergunta que inicialmente pode ser difícil de ser respondida, complexa ou simplesmente hipotético(kkkkk).

Foi então que eu comecei a buscar mais informações em um conceito que pra mim era realmente imaginário de ser adotado, e recentemente em um dos posts publicados nos fóruns de SQL Server aqui no Brasil veio a tona o chamado Índices Hipotéticos.

Essa é uma possível resposta quando estamos trabalhando com banco de dados, fazer uso de índices hipotéticos pode nos ajudar a identificar ou similar possíveis situações de impacto na performance de uma query durante sua execução, ainda mais se estivermos trabalhando com um conjunto volumoso de dados.

Para tentar compartilhar com você um pouco sobre este mistorioso recurso que podemos adotar em nosso ambiente, o post de hoje o próximo da sessão para que serve serão dedicados justamente ao entendimento, criação e uso dos índices hipotéticos.

E como de costume aquelas perguntas já conhecidas dos posts anteriores desta sessão:

E ai, você conhece esta funcionalidade? Já utilizou? Sabe para que ela serve?

Pois bem, estas e outras possíveis perguntas serão respondidas a partir de agora em mais este post da sessão Para que Serve!


Começa agora o #07 – Para que serve – Índices Hipotéticos – Parte I.

Mais um final de semana esta chegando, hoje sexta – feira, você já esta começando a se preparar para desligar sua estação de trabalho, pegar suas coisas e voltar para casa feliz por mais um dia de trabalho duro e gratificante e por saber que fez o melhor possível para manter tudo em ordem em seu local de trabalho, eis que após alguns minutos o seu ramal de telefone toca e no display aparece 2801 – Fernanda Galvão, meu deus você pensa, respira e atende sabendo que ela é a gerente de produção da empresa e para estar ligando no final do dia não deve ser nada muito simples, mesmo assim sabendo dos seus deveres e obrigações realiza o atendimento a ligação e escuta:

Junior Galvão, boa tarde!!!

Aqui é a Fernanda, tudo bem? Estamos com um pequeno problema na emissão do relatório de produção diária, estou aqui com o analista de produção João Pedro, você pode falar com ele?

Junior responde sim, claro!!!

Neste momento, João Pedro apresenta o cenário: Junior, olá boa tarde.

Estou com dificuldades para emitir o relatório de produção diária, ao tentar filtrar os dados por clientes e categoria de clientes, o sistema aparentemente entra em loop de processamento e os dados não são apresentados em tela. 

O que será que pode estar acontecendo? Alguns segundos se passam…. Junior começa a pensar e observa que seu final de semana aparentemente foi por água, ou melhor dizendo o final de semana não vai ser tão tranquilo.

Você responde: João Pedro, boa tarde, vou verificar o que pode esta acontecendo, sei que hoje realizamos algumas mudanças na estrutura da tabela de clientes e categoria de clientes, parece-me que o time de suporte adicionou um novo índice, vou tentar verificar.

João Pedro responde dizendo.

Ok! Junior, fico no aguardo, assim que você tiver uma posição por favor me informe.

Junior responde: Certo, perfeito, deixa comigo, vou verificar o que esta acontecendo garanto que hoje não vou conseguir dar uma resposta mais concreta!

Sabendo justamente que a equipe de suporte esta trabalhando para realizar alguns testes de performance nas tabelas de clientes e categoria de clientes, onde milhares de registros estão sendo processados diariamente, Junior chama um dos seus analistas de suporte Eduardo Galvão e pergunta:

Edu por acaso vocês realizaram alguma alteração na estrutura das tabelas de clientes ou categoria de clientes?

A resposta é simples e direta, sim Junior, estamos fazendo uso de um recurso que até então novo ou supostamente desconhecido para nossa equipe,  pelo que pesquisei é uma funcionalidade conhecida como índices que possuem somente estatíticas mas não existem fisicamente.

Junior responde: Índices somente com estatísticas, índices que não existem, que raio de recurso é esse, por acaso vocês estão se referindo a índices hipotéticos?

Eduardo responde, sim, sim, acredito que seja isso a analista de suporte de banco de dados Maria Luíza, esta fazendo um estudo sobre isso em nosso ambiente de testes e identificou que se fizermos a adoção deste recurso poderemos ter mais facilidade em reconhecer a necessidade de um novo índice ou se o mesmo realmente é útil mesmo após ter sido criado anteriormente.

Junior responde, certo Eduardo, mas este tipo de teste ou implementação deve ser planejada, não podemos simplesmente pesquisar um recurso na internet ou livros e já sair aplicando em nossos ambientes de teste, muito menos em produção, devemos sempre por em prática nosso check-list de boas práticas e principalmente ter um ambiente de contigência caso algo aconteça de errado.

Quero saber qual será a forma para identificar o que esta acontecendo e como vamos resolver este problema até segunda – feira, questiona Junior!!!”

Muito bem, este é nosso cenário, com base, nesta pequena estória que acabamos de conhecer, será criado nosso ambiente de testes para colocar em prática o conceito de índices hipotéticos, antes disso iremos comecer um pouco mais sobre este conceito.

Índices

Falando de uma maneira simples quando criamos um novo índice no SQL Server ou em qualquer outro banco de dados, estamos criando uma estrutura que basicamente servirá como caminho na busca e identificação de um ou mais dados solicitados pelos mecanismos de banco de dados durante o processamento de uma determinada query.

Ao realizar a criação deste elemento normalmente os índices físicos apresentam em sua estrutura os dados, distribuídos de maneira demográfica confome as manipulações são realizadas, além disso, apresentam densidade, granularidade e seletividade de acordo com seu conjunto de valores, com isso, temos um conjunto de informações técnicas conhecidas como estatísticas do índice o que permite servir como elemente auxiliar no obtenção mais ágil e simples dos dados solicitados.

Índices Hipotéticos

Ao se falar de índices hipotéticos, estamos se referindo a uma estrutura completamente oposta, sem qualquer tipo estrutura física, muito menos dados, um índice hipotético é conhecido como algo imaginário que não possue estrutura física, somente estrutura lógica ou seja, somente estatísticas que podem servir como recurso para tentar criar o mecanismo de banco de dados e também o plano de execução por parte do SQL Server na busca de um ou mais dados.

Como podemos criar um índice hipotético?

A partir do SQL Server 2008 R2 a Microsoft adicionou uma opção no comando Create Index conhecido como With Statistics_Only, traduzindo ao pé da letra para o português vamos encontrar ao similar à somente estatísticas. É com base nesta opção não documentada que temos a possibilidade de fazer uso de índices hipotéticos em nossos bancos de dados.

O uso desta opção é muito simples, basta ao final da linha de comando que referencia a criação de um novo índice adicionar a instrução With Statistics_Only = 0, onde o mecanismo de banco de dados vai entender que esta novo índice deverá ser criado possuindo somente uma estrutura lógica controlada e direcionada através dos dados estatísticos coletados durante as manipulações de dados ou execução de querys que fazem uso do mesmo. Quando criamos um novo índice e não informamos esta opção por padrão o mecanismo de banco de dados repassa internamente para processador de querys que este índice deve ser criado da maneira padrão ou seja, um índice que conterá estrutura física e lógica, e o valor correspondente a instrução With Statistics_Only será igual á -1, ou seja:

  • With Statistics_Only = 0 — Indica que o índice deve ser criado de maneira hipotética, índice forma somente por estrutura lógica, conhecida como estatíticas; e
  • With Statistics_Only = -1 — Indica que o índice deve ser criada da maneira clássica, índice formado por estrutura física e lógica.

Uma forma simples é fácil para saber se um ou mais índices apresentam esta diferença pode ser encontrada na visão de sistema sys.indexes através da coluna is_hypothetical, onde a mesma deverá apresentar os valores: 0(zero) ou 1(hum), sendo estes valores que identificam e diferenciam a ocorrência da existência de um ou mais índices clássicos e hipotéticos.

Mas não tudo sem flores como diria meu irmão, a criação de um índice hipotético é fácil, tranquila, sem muitos segredos. Agora, imagine se você deseja orientar otimizador de consultados existentes no SQL Server no uso deste tipo de índice durante o processamento de uma query, ou então se você deseja omitir o seu uso, situação que pode parecer muito comum de ser realizada ou automática, mas não é bem assim.

Temos a necessidade de dirigir isso mesmo, mostrar o caminho que deve ser seguido pelo Database Engine em conjunto com o Query Optimizer e posteriormente o Execution Plan, como deve ser feito o uso de um índice hipotético. Isso parece ser algo bastante complicado, não é bem assim, como sempre existe uma solução que a Microsoft muitas vezes também não reconhece como recurso documentado ou simplesmente não documento, e ai mais uma vez “Mister M de SQL Server” surge para nos ajudar e apresentar ao mundo como uma possível solução pode ser adotada maneira mais suave, mostrando como podemos  resolver este problema e sair desta sinuca de bico.

Pra variar surge para muitos um novo  DBCC – Database Command Console não documentado conhecido como DBCC AutoPilot e uma nova diretiva Set AutoPilot, onde:

  • Set AutoPilot – Orienta o query optimizer a considerar ou não o uso do índice hipotético no momento da criação do plano de execução da query; e
  • DBCC AutoPilot – Orienta o query optimizer fazer uso do índice hipotético de acordo com o conjunto de parâmetros a ser utilizado e posteriormente repassado para o plano de execução.

Preste atenção o nome dele não tem nada haver com piloto de Fórmula 1 (kkkk), vou repetir o seu nome DBCC AutoPilot e ele vai justamente nos ajudar e saber mais sobre os dados que estão relacionados com um determinado índice hipotético.

DBCC AUTOPILOT

Este comando DBCC é mais um dos diversos comandos de console de banco de dados que a Microsoft não reconhece como comando documentado ou suportado nativamente, através do conjunto de instruções “parâmetros” que compõem sua sintaxe o query optimizer vai se comportar de uma determinado maneira ou de outra.

Abaixo apresento a relação de parãmetros que formam o DBCC AutoPilot:

Parâmetro

Descrição
typeid Existem alguns valores, os mais utilizados basicamente são:
Type ID = 5: Iniciar a sessão ou comandos anteriores limpos;
Type ID = 0: Fazer uso de índices não clusterizados; e
Type ID = 6: Usar apenas índices clusterizados.
dbid Id do banco de dados habilitado para executar o comando.
maxQueryCost Supostamente definir um possível custo em relação ao processamento da query. “Sinceramente não entendi bem como usar (kkkk)”
tabid Id da Tabela a ser utilizada.
indid Id do índice a ser utilizado.
pages Ao executar o DBCC AutoPilot simular o comportamento e uso de páginas de dados.
flag Parâmetro desconhecido, não encontrei informações sobre ele….
rowcounts Parâmetro utilizado para definir o número de linhas de execução e processamento para alguns comandos.

Bom vou deixar você agora com um gostinho de quero mais, como destacado anteriormente este é a primeira parte deste Para que serve…. Na segunda parte vamos criar nossos índices hipotéticos e fazer uso da diretiva SET AutoPilot, posteriormente na terceira parte vamos utilizar a não documentada DBCC AutoPilot.


É isso ai galera, chegamos ao final de mais post da sessão Para que serve!

Espero que você tenha gostado, que as informações compartilhadas aqui possam lhe ajudar a se tornar cada vez um profissional de banco de dados reconhecido e valorizado, um dos papéis na área de tecnologia mais importantes para qualquer empresa.

Reconher o verdadeiro papel de um DBA dentro de sua estrutura, é reconhecer o verdadeiro valor de seus dados e como eles podem se tornar uma infomação valiosa para sua tomada de decisão.

Caso deseje acessar os posts anteriores desta sessão, utilize os links listados abaixo:

Short Scripts – Junho 2016


Salve, salve minha gente, boa tarde!!!

Mais uma segunda – feira começando e mais uma semana se iniciando, já passamos da metade do mês de Junho tão aguardado devido ao lançamento do novo Microsoft SQL Server 2016. Caso você tenha perdido alguma informação sobre este lançamento, aproveito para compartilhar aqui um dos diversos posts publicados no meu blog sobre esta nova versão:

Voltando a falar sobre o Short Scripts, esta é uma das sessões mas visitadas do meu blog, onde o objetivo  é compartilhar os scripts existentes em minha biblioteca de códigos  dedicados exclusivamente para o SQL Server. Muitos destes scripts são resultado de pesquisas, posts publicados nos fóruns MSDN e também de respostas encontradas em outros websites de profissionais, administradores de banco de dados, professores e comunidades.

Boa parte deste material é fruto de um trabalho dedicado exclusivamente a colaboração com a comunidade, visando sempre encontrar algo que possa ser a solução de um determinado problema, bem como, a demonstração de como se pode fazer uso de um determinado recurso. Todos os scripts publicados nesta sessão são devidamente testados antes de serem publicados, mas isso não significa que você pode fazer uso dos mesmo em seu ambiente de produção, vale sim todo cuidado possível para evitar maiores problemas.

Caso você não tenha acessado os últimos posts, não perca tempo, utilize os links publicados a seguir:

https://pedrogalvaojunior.wordpress.com/2016/03/22/short-scripts-marco-2016/

https://pedrogalvaojunior.wordpress.com/2015/12/14/short-script-dezembro-2015/

https://pedrogalvaojunior.wordpress.com/2015/10/21/short-scripts-outubro-2015/

https://pedrogalvaojunior.wordpress.com/2015/08/26/short-scripts-agosto-2015/

https://pedrogalvaojunior.wordpress.com/2015/06/03/short-script-junho-2015/

Para esta relação você vai encontrar scripts relacionados aos seguintes assuntos, conceitos, recursos ou funcionalidades:

  • Acesso a banco de dados;
  • Collation;
  • Comando Exec;
  • Comando Union;
  • Comando Union All;
  • Comando Create Table;
  • Comando Alter Table;
  • Common Table Expression;
  • DBCC CheckPrimaryFile;
  • DMV sys.dm_db_index_usage_stats;
  • DMV sys.dm_os_buffer_descriptors;
  • Índices Clustered e NonClustered;
  • Option MaxRecursion;
  • Plano de Execução;
  • Querys consideradas pesadas;
  • Tabela de sistema sys.allocation_units;
  • Tabela de sistema sys.partitions;
  • Tabela de sistema sys.indexes;
  • Tabela e caracteres Unicode; e
  • Recursividade.
A seguir, apresento a relação de short scripts:

— Short Script 1 – DBCC CheckPrimaryFile Verificando se o arquivo realmente é um Primary File —
DBCC CheckPrimaryFile (‘C:\Bancos\Laboratorio.MDF’,0)
Go

 

— Short Script 2 – DBCC CheckPrimaryFile – Retornando o conjunto completo de informações associados ao Primary File que formam a estrutura do respectivo Banco de Dados —
DBCC CheckPrimaryFile (‘C:\Bancos\Laboratorio.MDF’,1)
Go

 

— Short Script 3 – DBCC CheckPrimaryFile – Retornando o nome do banco de dados, versão e collation relacionados ao Primary File —
DBCC CheckPrimaryFile (‘C:\Bancos\Laboratorio.MDF’,2)
Go

— Short Script 4 – DBCC CheckPrimaryFile – Retornando o status, fileid, name e filename associados ao Primary File que formam a estrutura do respectivo Banco de Dados —
DBCC CheckPrimaryFile (‘C:\Bancos\Laboratorio.MDF’,3)
Go
— Short Script 5 – Informações sobre acesso ao Banco de Dados —
WITH agg AS
(SELECT last_user_seek,
                  last_user_scan,
                  last_user_lookup,
last_user_update
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID()
)
SELECT last_read = MAX(last_read),
                 last_write = MAX(last_write)
FROM
(SELECT last_user_seek, NULL FROM agg
UNION ALL
SELECT last_user_scan, NULL FROM agg
UNION ALL
SELECT last_user_lookup, NULL FROM agg
UNION ALL
SELECT NULL, last_user_update FROM agg
) AS x (last_read, last_write);
Go

 

— Short Script 6 – Observando a mudança de comportamento após a troca de Collation —

CREATE TABLE [dbo].[Authors]
([id] [INT] NULL,
   [author] [VARCHAR](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
   [dateposted] [DATE] NULL) ON [PRIMARY]
GO
INSERT Authors  VALUES (1, ‘Steve’, ‘20160101’),
                                                   (2, ‘STEVE’, ‘20160201’),
                                                   (3, ‘Andy’, ‘20160301’),
                                                   (4, ‘andy’, ‘20160401’)
GO
CREATE PROCEDURE GetAuthors @author VARCHAR(50)
AS
BEGIN
SELECT a.id, a.author FROM dbo.Authors a
WHERE a.author = @author
END
GO
— If I run the procedure with a parameter of ‘Steve’, it returns two rows. I then run this code:
Exec GetAuthors ‘Steve’
Go
ALTER TABLE dbo.Authors
ALTER COLUMN author VARCHAR(50) COLLATE SQL_Latin1_General_CP437_BIN2 NULL
— If I were to execute the stored procedure, what would happen?
Exec GetAuthors ‘Steve’
Go

 

— Short Script 7 – Descobrindo o código Unicode de um caracter ou String —

— Exemplo 1 —
DECLARE @n CHAR(10);
SET @n = N’Abc’;
SELECT UNICODE(@n);
Go
— Exemplo 2 —
DECLARE @n NCHAR(10);
SET @n = N’??????????’;
SELECT UNICODE(@n);
Go

 

— Short Script 8 – Criando CTEs —

— Exemplo 1 – Criando uma simples CTE —
;With Exemplo1(Valor, Nome)
As
(
Select 1, ‘Pedro Galvão’ As Nome
)
Select * from Exemplo1
Go
— Exemplo 2 – Criando uma CTE com Union de Selects —
;With Exemplo2(Valor)
As
( Select 10
Union
Select 50
Union
Select 8
Union
Select 10 + 2
)
Select Valor = (Select Max(valor) From Exemplo2) + (Select Sum(Valor) From Exemplo2)
Go
– Short Script 9 – Criando CTEs com Recursividade —
— Exemplo – Criando uma nova CTE Recursiva concatenando dados —
;With ConcatenarNomes(nome)
AS
( SELECT Nome = CONVERT(Varchar(4000),’Pedro Antonio’)
UNION ALL
SELECT CONVERT(Varchar(4000),nome + ‘ Galvão Junior’) FROM ConcatenarNomes
WHERE LEN(nome) < 30
)
SELECT Nome FROM ConcatenarNomes
Go
— Exemplo 2 – Criando uma CTE com Union + Recursividade – Simulando uma sequência de números pares —
;With CTENumerosPares(Numero)
As
( Select 0 As Numero
Union All
Select Numero + 2 As Numero From CTENumerosPares
Where Numero < 100
)
Select Numero From CTENumerosPares
Go
— Exemplo 3 – Criando uma CTE com Union + Recursividade – Simulando uma sequência de números —
;With CTENumerosSequenciais(Numero)
AS
(   SELECT 1 AS Numero
UNION ALL
SELECT Numero + 1 AS num FROM CTENumerosSequenciais
WHERE Numero < 1000
)
SELECT * FROM CTENumerosSequenciais
OPTION (MAXRECURSION 0)
Go
— Short Script 10 – Obtendo o tamanho de índices Clustered e NonClustered —
SELECT COUNT(*) AS cached_pages_count,
COUNT(*)/128.0000 MB,
name AS BaseTableName,
IndexName,
IndexTypeDesc
FROM sys.dm_os_buffer_descriptors AS bd
INNER JOIN (SELECT s_obj.name,
s_obj.index_id,
s_obj.allocation_unit_id,
s_obj.OBJECT_ID,
i.name IndexName,
i.type_desc IndexTypeDesc
FROM
(SELECT OBJECT_NAME(OBJECT_ID) AS name,
index_id,
allocation_unit_id,
OBJECT_ID
FROM sys.allocation_units AS au INNER JOIN sys.partitions AS p
ON au.container_id = p.hobt_id
AND (au.TYPE = 1 OR au.TYPE = 3)
UNION ALL
SELECT OBJECT_NAME(OBJECT_ID) AS name,
index_id,
allocation_unit_id,
OBJECT_ID
FROM sys.allocation_units AS au INNER JOIN sys.partitions AS p
ON au.container_id = p.partition_id
AND au.TYPE = 2
) AS s_obj LEFT JOIN sys.indexes i
ON i.index_id = s_obj.index_id
AND i.OBJECT_ID = s_obj.OBJECT_ID
) AS obj ON bd.allocation_unit_id = obj.allocation_unit_id
WHERE database_id = DB_ID()
and name not like ‘sys%’
and IndexName <> ‘null’
GROUP BY name, index_id, IndexName, IndexTypeDesc
ORDER BY cached_pages_count DESC;
Muito bem, mais uma relação de short scripts acaba de ser compartilhada, mesmo sendo denominados short entre aspas “pequenos”, posso garantir que todos estes exemplos são de grande importância e apresentam um valor e conhecimento do mais alto nível.

Chegamos ao final de mais um post, fique a vontade para compartilhar este conteúdo com seus contatos e redes sociais, contribua também enviando dicas, sugestões, dúvidas, críticas, enfim participe e ajude a melhorar cada vez mais esta sessão.

Mais uma vez obrigado por sua visita, nos encontramos em breve em mais um post da sessão Short Scripts.

Uma ótima semana, abraços.

#05 – Para que serve


Hello everybody, Good Afternoon, Buenas Tardes e Buon pomeriggio!!!!

Domingão chuvoso aqui em São Roque, olha esta chuvinha já esta dando o que falar e causando alguns estranhos na região, poxa vida eu gosto de chuva mas acho que já deu na hora de parar(kkkkk), desse jeito vamos ficar todos embolorados(kkkkkk)….

Comentários e brincadeirasa parte, aproveitando este tempinho para ficar em casa se preparando para mais uma semana de muito trabalho no FIT e na FATEC, falando de FATEC já estamos chegando ao final do semestre.

Pois bem, estava pensando e decidi compartilhar com vocês na sessão Para que serve, mais dois comandos DBCCs (Database Command Console) não documentadas que recentimente acabei me deparando em uma necessidade na empresa e por incrível que pareça uma das QoD (Question of Day) no portal SQLServerCentral.com, alias eu sou suspeito a falar deste portal, sou fã de carterinha desta plataforma que emana conhecimento especializado e dedicado ao Microsoft SQL Server.

Seguindo em frente, estou me referindo a DBCC Freeze_IODBCC Thaw_IO! Por acaso você já teve a necessidade de utilizar ou já ouvi falar destes commandos?

Ficou surpreso em saber da existência destes recursos, eu também, mas tenho a certeza que você vai ficar mais supreso quando fazer uso deles, algo que realmente pode ajudar em muito a entender o comportamento do SQL Server durante o procedimento de leitura e escrita de uma transação.

Bom vamos conhecer um pouco mais sobre estas duas DBCCs não documentadas, tendo como base um tradicional ambiente de testes que normalmente utilizo para este tipo de necessidade, e como de costume, vamos vais uma vez resaltar que este tipo de procedimento deve ser realizado sempre em ambientes ou cenários de teste e desenvolvimento, pois são comandos que podem alterar o comportamento do seu servidor ou instância SQL Server, proporcionando algum tipo de perda de informação ou impactos nos seus dados. Mesmo assim acredito que vale a pena conhece-los.


Começa aqui o #05 – Para que serve, boa viagem meu amigo.

Basicamente estas duas DBCCs não documentadas estão presentes na relação de comandos não oficiais e não reconhecidos pela documentação Microsoft á algum tempo, nas pesquisas que realizei para obter mais exemplos e informações encontrei posts publicados em alguns blogs americas, russos e europeus datados de meados do ano de 2011, sendo assim deduzido que ambas as funcionalidades podem ser utilizadas de uma maneira mais “segura” nas versões 2008 R2, 2012 e 2014.

Para nosso ambiente de testes vou utilizar o Microsoft SQL Server 2014 Express SP1, também realizei testes no Microsoft SQL Server 2012 Express SP3, não observei nenhum tipo de mudança de comportamento ou processamento em relação a cada versão, tanto na sua forma de execução como também na maneira de processamento o resultado obtive foi o mesmo, sendo assim, fique a vontade para escolher a versão que você deseja utilizar. Então vamos conhecer um pouco sobre cada comando DBCC, começando pela DBCC Freeze_IO.

DBCC Freeze_IO

Como seu próprio nome segure, esta dbcc tem a função de congelar de forma temporária do processo de leitura e escrita realizada para um banco de dados, quando eu me referi a congelar estou fazendo referência a possibilidade de suspender todo processo de IO(Input – Output) para gravação de dados no banco de dados que você encontra conectado.

Quando o DBCC Freeze_IO é executado todas as atividades realizadas pelo SQL Server que envolvam processos de IO que estejam vinculadas a operação de escrita serão suspensas, não estou dizendo que estas atividades vão receber uma instrução de encerramento ou finalização, nada disso todas serão congeladas até que o comando DBCC Thaw_IO seja executado.
Uma vez que o IO é congelado, você pode tratar o banco de dados como um banco de dados somente leitura. Qualquer atividade de escrita não retornará nenhum tipo de informação, pois este banco de dados terá naquele exato momento o comportamento de um banco somente leitura. 
Você pode estar se pergunta, cara isso é muito perigo? Sim a resposta é sim, ainda mais se você fizer uso deste tipo de implementação em um ambiente que sofre uma carga enorma de leitura e escritas em pouco espaço de tempo.
DBCC Thaw_IO
Como destacado anteriormente este comando DBCC tem a finalidade de descongelar ou remover o status de suspensão nos processos de leitura e escrita marcados pela DBCC Freeze_IO. Quando executado o DBCC Thaw_IO envia para o Database Engine uma instrução que permite reverter o estado do banco de dados de somente leitura para leitura e escrita, desta forma, o SQL Server entende que a partir daquele momento o banco de dados envolvimento na execução da DBCC Freeze_IO não necessita mais ser impedido de receber novos dados, como também, esta livre para retornar qualquer tipo de informação solicitado pelo usuário e suas aplicações.
Ufa, parece ser bastante assustador fazer uso destes dois comandos, mas não é bem assim, e para mostrar que nem tudo o que parece realmente é tão perigoso, vamos fazer uma pequena prática para ilustrar o comportamento do SQL Server durante a execução de cada DBCC, para isso iremos utilizar uma pequena tabela chamada Estudantes, chegou então a hora de colocar a mão na massa ou melhor no código (kkkkk)….

Colocando a mão no código #05 – Para que serve – DBCC Freeze_IO e DBCC Thaw_IO

Para nosso ambiente de testes, vamos criar um novo banco de dados chamado DBFreeze e como destacado anteriormente será criada uma tabela chamada Estudantes que receberá alguns linhas de registros, conforme apresenta o bloco de Código 1 a seguir:
— Código 1 —

— Criando o Banco de Dados DBFreeze —

Create Database DBFreeze

Go

 

— Acessando o Banco de Dados —

Use DBFreeze

Go

 

— Criando a Tabela Estudantes —

Create Table Estudantes

(Id Int Primary Key Identity(1,1),

Nome Varchar(20) Not Null,

Classificacao TinyInt Not Null,

Curso Varchar(20) Not Null)

Go

 

— Inserindo os dados —

Insert Into Estudantes (Nome, Classificacao, Curso)

Values (‘Kim’, 99, ‘Inglês’),

(‘Thomas’, 95, ‘Inglês’),

(‘Jonh’, 92, ‘Inglês’),

(‘Mag’, 97, ‘Espanhol’),

(‘Sussy’, 90, ‘Espanhol’),

(‘Boby’, 91,‘Português’),

(‘Darth’, 89, ‘Português’)

Go 100000

 

Ótimo, nosso ambiente este criado, agora podemos fazer uma simples simulação do congelamento do banco de dados DBFreeze, para isso vamos utilizar o bloco de código 2, note que iremos executar um simples select com algumas funções de ranking na tabela Estudantes, conforme apresento abaixo:

 

— Código 2 —

Begin Transaction

Select Id, Nome, Classificacao, Curso,

ROW_NUMBER() Over (Order By Curso) As ‘Row Number’,

Rank() Over (Order By Curso) As ‘Rank’,

Dense_Rank() Over (Order By Curso) As ‘Dense Rank’,

NTile(4) Over (Order By Curso) As ‘NTile’

From Estudantes

Go

Observe que para garantir e evitar qualquer tipo de impacto em outras transações, realizei a abertura de uma nova transação para que o comando select e suas respectivas funções de ranking fossem executadas, neste momento esta transação esta sendo executado, vamos então forçar o congelamento do banco de dados, para isso abra uma nova query em seu management studio e execute o bloco de código 3:

— Código 3 —

DBCC Freeze_IO(DBFreeze)
Go

A partir deste momento nosso banco de dados DBFreeze acaba de receber a instrução de Freeze IO, onde o mesmo vai ser obrigado a interromper qualquer processo de atividades que envolvam leitura e escrita de dados, se você decidir voltar a sessão anterior, será possível observar que a mesma continua em execução mas os dados não são retornados em tela, para ter certeza de qual é o atual status desta sessão, podemos fazer uso da system stored procedure sp_lock para obter a lista de recursos e objetos atualmente em lock em nosso SQL Server.

Vamos voltar nosso banco de dados para o estado original, possibilitando que todas as leituras e escritam possam ser executadas normalmente retornando os dados solicitados, para isso utilizaremos o bloco código 4 apresentado a seguir. Para sua execução recomendo utilizar a mesma query criada para execução do código 3:

 

— Código 4 —

DBCC Thaw_IO(9)

Go

Após alguns segundos o Database Engine entende que o nosso banco de dados DBFreeze deve ter o estado de somente leitura alterado para leitura e gravação, sendo assim, o processamento da nossa primeira query será executado e encerrado normalmente, onde teremos todos os nossos dados apresentados conforme a estrutura do comando select executada no bloco de código 2, ilustrado anteriormente.

Observações:

  1. Gostaria de salientar que este tipo de funcionalidade não será muito aplicável ou utilizável em suas atividades diárias, mas poderá ser bastante útil quando você desejar de alguma forma simular uma possível “imagem ou snapshot” do seu banco de dados em um espaço de tempo ou situação; e
  2. O uso do DBCC Freeze_IO, DBCC Thaw_IO e qualquer outro comando DBCC não reconhecido ou documentado pela Microsoft e seus times de Engenheiros e desenvolvedores deve ser utilizado com muita cautela e sempre em ambientes de testes e desenvolvimento. Em algumas situações a adoção de estratégias de backup de bancos de dados ou até mesmo de um snapshot de seu ambiente virtualizado devem ser adotados como forma de garantir a recuperação dos seus recursos.

Então chegamos ao final de mais um post, estamos vivos e salvos e principalmente nosso banco de dados sobreviveu.


É isso ai galera, muito legal este post da sessão Para que serve!

Espero que você tenha gostado, que as informações compartilhadas aqui possam lhe ajudar a se tornar cada vez um profisisonal de banco de dados mais reconhecido e valorizado, algo que atualmente as empresas estão deixando muito de reconhecer o verdadeiro papel de um DBA que muitas vezes passa despercebido, mas é de grande e extremo valor para qual instituição, empresa ou corporação.

Caso deseje acessar os posts anteriores desta sessão, utilize os links postados abaixo:

Mais uma vez obrigado por sua visita, tenha uma ótima semana, nos encontramos em breve.

Até mais.

#04 – Para que serve


Eita mundo bão, boa noite galera, tudo bem?

Final de noite de sábado e após mais uma longa semana de muito trabalho, estou novamente aqui no meu blog para finalizar mais um mês com o post da sessão Para que serve.

No post de hoje vou compartilhar uma funcionalidade que particularmente não conhecia no SQL Server até o começo desta semana, estou me referindo a mais um DBCC – Database Command Console não documentada existente no Microsoft SQL Server, fazendo parte da longa lista de DBCC não documentadas, assunto que eu por diversas vezes já destaquei no meu blog e principalmente nos fóruns MSDN/TechNet.

Estou me referindo a DBCC CheckPrimaryFile, ao encontrar os primeiros posts sobre este commando fiquei surpreso com sua existência, ainda mais por que o cenário que eu me deparei com o uso do mesmo, por diversas outras oportunidade tive a necessidade de fazer aplicar uma possível solução muito parecida ou praticamente idêntica ao que este database command realiza, e ai acabei fazendo um questionamento para eu mesmo, poxa vida como eu nunca me atentei para esta funcionalidade.

Então tomei a descisão de buscar mais informações sobre este recurso e como de costume vamos fazer uso da internet para tentar descobrir mais informações sobre este DBCC. Não consegui encontrar muitas informações, sobre sua origem ou ator, dentre os principais posts que coletei informações foi possível identificar que trata-se de um recurso/funcionalidade presente no SQL Server desde a versão 2005 e mantida neste momento na versão 2014.

Levando-se em consideração as informações que encontrei durante as pesquisas que realizei, fica difícil afirmar se o time de desenvolvimento e engenharia do SQL Server vai manter este recurso de forma oculta na versão 2016 ou talvez venha a remover a compatibilidade da mesma. Mesmo assim, acredito que vale a pena conhecer um pouco mais sobre este comando, sua finalidade, forma de uso e principalmente em qual tipo de cenário pode ser interessante fazer uso deste recurso.

Vamos em frente, é chegada a hora, começa aqui o #04 – Para que serve – DBCC CheckPrimaryFile

Conhecida como um dos Database Command Console “não oficial” ou “não documentada” existente de forma no Microsoft SQL Server desde a versão 2005 e compátivel atualmente com a versão 2014 e suas edições a DBCC CheckPrimaryFile, tem como finalidade possibilitar ao DBA ou qualquer profissional que esteja naquele momento tendo a necessidade de descobrir se um determinado arquivo de dados (conhecido como arquivo .MDF – Master Data File), pode ser reconhecido como o arquivo primário (primary file) que compõem a estrutura física e lógica de respectivo banco de dados.

A DBCC CheckPrimaryFile apresenta uma sintaxe e forma de uso simples, composta por dois parâmetros:

  • PhysicalFileName: Representa e identifica o nome físico do arquivo de dados relacionado a um determinado banco de dados; e
  • Opt: Parâmetro composto por um conjunto de quatro valores sendo eles:
    • 0 – Verifique se o physical file name informado realmente representa e consiste como arquivo de dados primário;
    • 1 – Apresenta como retorno as colunas name, size, maxsize, status and path de todos os arquivos associados ao respectivo physical file name;
    • 2 – Apresenta como retorno as colunas databasename, version e collation do respectivo physical file name; e
    • 3 – Apresenta como retorno as colunas name, status e path do respectivo physical file name informado.

Exemplo:

  • DBCC checkprimaryfile (‘PhysicalFileName’, 0)

Dentre os principais cenários relacionados á este DBCC, estão associados as mensagens de erro 5171 e 5172 apresentadas pela Microsoft SQL Server, sendo elas:

  • An exception occurred while executing a Transact –SQL statement or batch. _db.mdf is not a primary database file. (Microsoft SQL Server, Error: 5171).”
  • is not a primary database file. (Microsoft SQL Server, Error: 5171)
  • Server: Msg 5172, Level 16, State 15, Line 1 The header for file path……\.mdf is not a valid database file header. The PageAudit property is incorrect.”

Basicamente estas mensagens relacionadas aos erros: 5171 e 5172 são apresentados pelo SQL Server em operações que envolvam as possíveis transações de:

  • Attach Database;
  • Attach Database a Single File; e
  • Restore Database.

Além disso, estas mensagem de erro normalmente são indicadores que a estrutura física e lógica dos arquivos de dados existentes a um determinado banco de dados podem estar corrompidas, algo que pode representar em diversas situações possíveis perdas de dados ou risco de seu banco de dados estar totalmente danificado ou condenado.

Agora é chegado a hora de por a mão na massa, vamos executar o DBCC CheckPrimaryFile e observar o conjunto de dados apresentados em cada das suas formas de uso, para este cenário de teste estou utilizando o Microsoft SQL Server 2014 Express em meu ambiente de teste e desenvolvimento. Aproveito a oportunidade para destacar que este tipo de comando não deve ser utilizado em servidores de produção ou ambientes que possuam grande volume de acesso por parte dos usuários, bem como dados de grande importância para você ou sua empresa.

Uma dica importante sempre que você for realizar qualquer tipo de teste sem conhecer um determinado comando ou funcionalidade é altamente recomendável a realização de backup dos seus principais bancos de dados.

— Exemplos de utilização – DBCC CheckPrimaryFile —


— Verificando se o arquivo realmente é um Primary File —
DBCC CheckPrimaryFile (‘C:\Bancos\Laboratorio.MDF’,0)
Go

DBCC CheckPrimaryFile - 0

— Retornando o conjunto completo de informações associados ao Primary File que formam a estrutura do respectivo Banco de Dados —
DBCC CheckPrimaryFile (‘C:\Bancos\Laboratorio.MDF’,1)
Go

DBCC CheckPrimaryFile - 1

— Retornando o nome do banco de dados, versão e collation relacionados ao Primary File —
DBCC CheckPrimaryFile (‘C:\Bancos\Laboratorio.MDF’,2)
Go

DBCC CheckPrimaryFile - 2

— Retornando o status, fileid, name e filename associados ao Primary File que formam a estrutura do respectivo Banco de Dados —
DBCC CheckPrimaryFile (‘C:\Bancos\Laboratorio.MDF’,3)
Go

DBCC CheckPrimaryFile - 3

Você pode notar que após a execução de cada uma das respectivas formas de uso existentes no DBCC CheckPrimaryFile, o conjunto de dados retornados pelo Microsoft SQL Server é apresentado de acordo com os valores informações no physical file name mas principalmente ao número que representa a opção e conjunto de valores deve ser retornados em tela.

Importante destacar a necessidade do usuário que encontra-se conectado no momento da execução deste DBCC em seu servidor ou instância SQL Server ter permissão de acesso ao local em que seu arquivos .mdf, .ndf e .ldf que formam a estrutura física do seu banco de dados estejam armazenados fisicamente.


Sendo assim chegamos ao final……Eita nóis, consegui, ou melhor conseguimos, estamos vivos em mais um post dedicado a sessão Para que serve, foi muito legal poder compartilhar com vocês este Database Command Console existente a muitos anos no SQL Server.

Desejo e torço para que você tenha gostado das informações aqui compartilhadas, caso tenha interesse em acessar os outros posts desta sessão não perca tempo, utilize os links apresentados abaixo e boa viagem meu amigo:

  1. https://pedrogalvaojunior.wordpress.com/2016/04/08/03-para-que-serve/
  2. https://pedrogalvaojunior.wordpress.com/2016/02/26/02-para-que-serve/
  3. https://pedrogalvaojunior.wordpress.com/2016/01/28/01-para-que-serve/

Um grande abraço! Obrigado por sua participação e visita, bom fim de noite e um ótimo domingo.

Transferindo a estrutura de uma tabela no Microsoft SQL Server 2008, 2012 e 2014 através da opção Switch


Olá pessoal, bom dia!!!

Tudo bem? Segunda – feira começando, já estamos no Outono, meados do mês de Abril de 2015, e o tempo passando, e como sempre todos nós tentando acompanhar esta frenética correria do dia-a-dia.

O engraçado é justamente isso, este agito, esta loucura, esta busca por ultrapassar obstáculos que muitas vezes acaba nos limitando ou até mesmo impedindo de procurar encontrar soluções simples para nossas necessidades.

Foi um simples bate-papo com um amigo de trabalho, que me fez pensar e escrever este artigo, levando em consideração uma simples solução que utilizamos na semana passada para simular e resolver o que parecia ser um grande problema, mas que na verdade era algo bastante simples.

 

Introdução

O cenário como de costume parecia ser bastante estranho, transferir dados entre tabelas em um banco de dados no Microsoft SQL Server sem fazer uso do comando Insert, de cara eu pensei um utilizar o comando Select….Into, mas na verdade não era isso o que precisávamos, pois a tabela que iria receber os dados já existia, então o Select…Into veio por água abaixo.

Outras soluções como BPCP, Bulk-Insert, SQLCMD e SSIS foram pensadas mas por limitações do escopo não permitidas, foi ai que questionamentos novamente o cenário e reconhecemos que na verdade não era uma transferência de dados que deveria ser feita, o que realmente devíamos fazer para atender a necessidade apresentada era transferir a estrutura de uma tabela com todo seu conjunto de informações para outra.

Você pode estar estranhando, como nós também achamos meio fora do comum, transferir a estrutura de uma tabela para outra, alguns questionamentos e até mesmo pensamos foram feitos, como por exemplo: Isso é que coisa de doido, que loucura…

Bom, deixamos de lado e seguimos em frente, nosso objetivo era transferir a estrutura de uma tabela para outra sem correr o risco de perder dados, como também, não alterar em nada todo ambiente criado e utilizado pelo cliente.

 

A busca pela solução….

Até ai, tudo bem estranho, confuso e até mesmo um pouco obscuro, mas como eu costume dizer vivendo, estudando e aprendendo, comecei a buscar um pouco mais de cenários similares a este e recorrer ao Pai de Todos do SQL Server, este me referindo ao Books On-Line e foi justamente nele que encontrei a solução simples e prática para nosso problema obscuro, utilizar a opção Switch existente no comando Alter Table.

Algo que sinceramente eu nunca tinha pensado, utilizar esta opção para transferir a estrutura física e lógica de uma tabela, era algo que me parecia ser algo de outro mundo, acabei sendo pego de surpresa e mais uma vez espantado com o poder e inteligência do Microsoft SQL Server.

 

Entendendo como a opção Switch trabalha

Vamos lá, acredito que você saiba que o comando Alter Table é utilizado no Microsoft SQL Server como recurso de linha de comando que permite alterar todo estrutura de uma tabela, desde a simples opção de adicionar ou remover uma coluna, como também, trabalhar com particionamento de dados, definir níveis de escalonamento, reindexação de índices, entre outros recursos e funcionalidades. O foco deste artigo não é explicar como utilizar o comando Alter Table, caso você queira saber mais acesse: https://msdn.microsoft.com/pt-br/library/ms190273.aspx

Seguinte em frente, vou destacar de forma resumido e bastante simples a opção Switch, esta opção foi introduzida no Microsoft SQL Server a partir da versão 2008 e presente na atual versão 2014, basicamente este recurso possui a finalidade de realizar a alteração de um bloco de dados que alocado a uma tabela ou partição.

Comportamento

Alterna um bloco de dados em um dos seguintes modos:

  • Reatribuir todos os dados de uma tabela como uma partição para uma tabela particionada já existente;
  • Alterna uma partição de uma tabela particionada para outra; e
  • Reatribuir todos os dados em uma partição de uma tabela particionada para uma tabela não particionada existente.

 

Considerações e Preocupações

Como estaremos fazendo a “transferência” atribuição de dados de uma partição que forma uma tabela única, devemos ter as seguintes preocupações:

    • A tabela de destino já deve ter sido criada e deve estar vazia
    • A tabela de origem ou a partição e a tabela de destino ou a partição devem residir no mesmo grupo de arquivos; e
  • Os índices correspondentes ou as partições de índice também devem residir no mesmo grupo de arquivos. 

 

 

Sintaxe

Alter Table Table_Name_Source

Switch To Table_Name_Destination

 

Então galera, agora que já conhecemos o que a opção Switch é capaz de fazer, seu comportamento, considerações e preocupações, sua sintaxe e forma de uso, podemos começar a colocar a mão na massa e brincar um pouco com este recurso. Para realizarmos a simulação do uso do Switch, vamos trabalhar com duas tabelas, denominadas:

  • TBOrigem; e
  • TBDestino

Vale ressaltar que ambas as tabelas terão a mesma estrutura, contendo quatro colunas:

Nome da Coluna Tipo de Dados e Constraint
Codigo Int Primary Key
Texto Varchar(100)
Contador UniqueIdentifier
datacadastro DateTime Default Getdate()

 

Agora mão na massa, começando pelo Passo 1 – Criando as Tabelas:

— Passo 1 – Criando as tabelas TBOrigem e TBDestino –

— Utilizando o banco de dados TempDB–

Use TempDB

Go

 

— Criando a Tabela TBOrigem —

Create Table TBOrigem

(Codigo Int Primary Key Identity(1,1),

Texto Varchar(100),

Contador UniqueIdentifier Not Null,

DataCadastro DateTime Default GetDate())

Go

 

— Criando a Tabela TBDestino —

Create Table TBDestino

(Codigo Int Primary Key Identity(1,1),

Texto Varchar(100),

Contador UniqueIdentifier Not Null,

DataCadastro DateTime Default GetDate())

Go

 

— Passo 2 – Inserindo a massa de dados na Tabela TBOrigem —

Insert Into TBOrigem (Texto, Contador)

Values(‘Este é um teste de transferência de estrutura…’, NEWID())

Go 10000

 

Você pode observar que o bloco de código é bastante simples, estamos inserindo uma massa considerável de dados, são 10.000 linhas de registros inseridas fazendo com que o SQL Server venha a distribuir esta estrutura de alocação de registros em diversas páginas de dados que estarão formando a estrutura física e lógica da Tabela TBOrigem.

Agora para começarmos a entender como a opção Switch vai trabalhar, vamos fazer uso do comando DBCC Ind, este é um dos comandos da categoria DBCCs que consta na lista de comandos ou recursos não documentadas pela Microsoft.

O comando DBCC Ind tem como finalidade apresentar as informações sobre as páginas de dados que compõem uma determinada tabela, para isso vamos utilizar o Passo 3, apresentado abaixo:

 

— Passo 3 – Consultando informações sobre as páginas de dados e estruturas das Tabelas —

DBCC Ind(‘TempDB’,’TBOrigem’,1)

Go

 

Note que ao executar o comando DBCC Ind na tabela TBOrigem o Management Studio nos retornou 115 linhas de registro que representam as páginas de formam nossa tabela levando-se em consideração também as páginas que podem formam o nosso índice clusterizado que está associado a chave primária. A Figura 1 apresentada a seguir ilustra o resultado do comando DBCC Ind:

Switch-Figura 1

Figura 1 – Informações sobre as páginas de dados que compõem a Tabela TBOrigem.

Para saber mais sobre o DBCC Ind acesse o SQL Server Store Engine Blog: http://blogs.msdn.com/b/sqlserverstorageengine/archive/2006/12/13/more-undocumented-fun_3a00_-dbcc-ind_2c00_-dbcc-page_2c00_-and-off_2d00_row-columns.aspx

Vale ressaltar que a partir da versão 2012 o DBCC Ind foi substituído pela DMF – Dynamic Management Function: SYS.DM_DB_DATABASE_PAGE_ALLOCATIONS, conforme apresenta Muhammad Imran em seu post: http://raresql.com/2013/01/24/sql-server-2012-sys-dm_db_database_page_allocations-dynamic-management-function/

 

Talvez você estar se perguntando, preciso executar o comando DBCC Ind para tabela TBDestino? A resposta é Não, pois neste momento a tabela TBDestino encontra-se vazia, ou seja, não existe nenhum tipo de páginas de dados que forma esta tabela.

Dando continuidade, agora é a hora de realmente colocarmos em prática o que queremos fazer, “transferir” ou “atribuir” a estrutura física e lógica da tabela TBOrigem para tabela TBDestino, fazendo uso da opção Switch em conjunto como comando Alter Table. Para tal, vamos executar o Passo 4 apresentado abaixo:

— Passo 4 – Transferindo a estrutura da Tabela TBOrigem para Tabela TBDestino —

Alter Table TBOrigem Switch To TBDestino

Go

 

Muito bem, a primeira parte do passo 4 foi executado, neste momento toda estrutura da Tabela TBOrigem foi repassada para a TBDestino, para começarmos a comprovar esta transferência, vamos executar os dois comandos Selects apresentados a seguir:

Select Codigo, Texto, Contador, DataCadastro from TBOrigem

Go

 

Select Top 100 Codigo, Texto, Contador, DataCadastro from TBDestino

Go

 

Após executar os comandos Selects, você deverá ter se deparado com o mesmo resultado apresentado para Figura 2:

Switch-Figura 2

Figura 2 – Resultado da execução dos comandos Selects.

Ai esta, em uma simples linha de código toda estrutura da Tabela TBOrigem, seus respectivos dados alocados em suas especificadas de páginas de dados foram realocados para a Tabela TBDestino sem realizarmos qualquer tipo de manipulação de dados através de comandos DML, algo fantástico, surpreendente e que nos permite pensar o quanto o Microsoft SQL Server em conjunto com suas funcionalidades e algoritmos é capaz de manipular seus objetos.

Agora para comprovar de forma definitiva, vamos executar o Passo 5, consultando a relação de páginas de dados que compõem nossas tabelas:

 

— Passo 5 – Transferindo a estrutura da Tabela TBOrigem para Tabela TBDestino —

DBCC Ind(‘TempDB’,’TBOrigem’,1)

Go

DBCC Ind(‘TempDB’,’TBDestino’,1)

Go

 

Após executar o passo 5, a caixa de Mensagens do Management Studio deverá apresentar o seguinte resultado, conforme ilustra a Figura 3:

Switch-Figura 3

Figura 3 – Mensagens apresentadas após a execução do comando DBCC Ind.

Além disso, ao executar o segundo DBCC Ind, você poderá observar e comprovar que as mesmas máquinas de dados que estavam vinculadas a Tabela TBOrigem foram repassadas para Tabela TBDestino, conforme apresenta a Figura 4:

Switch-Figura 4

Figura 4 – Execução do comando DBCC Ind, obtendo a relação de páginas de dados da Tabela TBDestino.

Conclusão

Falar do Microsoft SQL Server realmente não é fácil, ainda mais quando a resposta para um problema que parece ser de outro mundo, pode muitas vezes estar na nossa frente, o artigo que hoje mostrou justamente isso, o quando o SQL Server vem a cada versão evoluindo, demonstrando que é uma Plataforma de Gerenciamento de Banco de Dados em todos os aspectos e não simplesmente um mero repositórios de tabelas e registros.

Através da opção Switch introduzida no comando Alter Table a partir da versão 2008 do Microsoft SQL Server, temos a capacidade técnica de inferir diretamente na estrutura de alocação de uma tabela ou partição, algo que parecia ser tão complexo e custoso pode ser feito através de uma simples linha de código.

Acredito ter conseguido de forma clara, simples e didática apresentar uma forma de uso desta opção, sem requerer qualquer tipo de configuração específica ou até mesmo uso de recursos mais avançados, além disso, fizemos uso do comando DBCC Ind para obter as informações sobre as páginas de dados, sabemos que o mesmo a partir da versão 2012 foi substituído pela DMF: SYS.DM_DB_DATABASE_PAGE_ALLOCATIONS.

Espero que você possa ter gostado deste artigo, que as informações, links e exemplos possam lhe ajudar e permitir que você conheça cada vez mais o Microsoft SQL Server, seus segredos, recursos e diversidades de funcionalidades.

Vou fincado por aqui, mas uma vez obrigado por sua visita, nos encontramos em breve.

Até mais.