Dica do Mês – Microsoft SQL Server 2017 – SQL Graph Databases


Muito bom dia…… Salve amantes de banco de dados.

Tudo bem? Este é mais um post da sessão Dica do Mês, sessão dedicada a compartilhar mensalmente dicas, novidades, curiosidades e demais informações relacionadas ao Microsoft SQL Server, Banco de Dados e Tecnologias de Banco de Dados.

No post de hoje, quero compartilhar com você uma das maiores novidades implementadas na última versão do Microsoft SQL Server, neste caso, a versão 2017 lançada oficialmente em outubro de 2017 e muito destacada aqui no meu blog em diversos posts.

Destacando um pouco sobre o post, quando se referimos a banco de dados, normalmente pensamos em uma estrutura organizada basicamente em tabelas, colunas, chaves primárias, chaves estrangeiras e relacionamentos. Mas a partir do Microsoft SQL Server 2017 temos uma nova possibilidade de elaborar uma estrutura de banco de dados saindo um pouco deste tradicional cenário conhecimento como modelo relacional e sim partindo para o chamado modelo grafos ou banco de dados em grafos. Talvez em algum momento você já deve ter ouvido falar um pouco sobre esta forma de modelagem.

Pois bem, neste nova versão o time de engenheiros do SQL Server adicionaram ao conjunto de novas funcionalidades (features) o SQL Graph Databases ou simplesmente Banco de Dados em Grafos, isso mesmo banco de dados no formato de grafos, parece ser algo muito diferente do que estamos acostumados a fazer, na verdade não é bem assim, e você vai poder conhecer um pouco mais sobre este recurso, suas características e curiosidades no decorrer deste post.

Esta curioso em saber um pouco mais sobre esta nova feature? Eu estou, e não vejo a hora de poder dividir com você um pouco do vasto conteúdo relacionado com este recurso. Então, vamos em frente, vou tentar mitigar a sua curiosidade e ao mesmo também satisfazer os meus objetivos. Sendo assim, seja bem vindo ao post – Dica do Mês – Microsoft SQL Server 2017 – SQL Graph Databases.

Você vai se surpreender com este novo recurso e suas possibilidades relacionadas com modelagem de banco de dados.


Introdução

O SQL Graph Database é uma nova forma de se estruturar um banco de dados criado no Microsoft SQL Server 2017, tendo como base um estrutura formada por uma coleção de tabelas de nó (Node Table) e  tabelas de borda (Edge Table).

Basicamente um nó representa uma entidade — por exemplo, uma pessoa ou uma organização e uma borda representa uma relação entre os dois nós que ele conecta. As tabelas de nó ou borda podem ser criadas em qualquer esquema em um banco de dados, mas todas pertencem a uma estrutura de grafos representada de forma lógica.

Os bancos de dados na estrutura de grafos são úteis quando o aplicativo tem relacionamentos complexos de muitos para muitos e precisamos analisar as relações complexas.

Algumas das características importantes de um bancos de dados na estrutura de grafos:

  • Bordas (edge) ou relacionamentos(node) são entidades de primeira classe em um banco de dados de grafos e podem ter atributos ou propriedades associadas a eles;
  • Uma única edge table pode unir flexivelmente vários nós em um banco de dados de grafos;
  • Demonstrar a relação de padrões e consultas de navegação de vários saltos facilmente; e
  • Demonstrar o encerramento transitivo de dados e as consultas polimórficas facilmente.

A Figura 1 abaixo apresenta a estrutura básico do SQL Graph Databases e seus principais componentes:

Architecture of SQL Server 2017 Graph Database
Figura 1 – Estrutura básica do SQL Graph Databases.

Analisando a Figura 1 apresentada acima, podemos dizer que um banco de dados na estrutura de grafos é um tipo de banco de dados cujo conceito é baseado em nós e bordas. Este novo tipo de bancos de dados, denominada de grafos, baseiam-se na teoria dos grafos (um grafo é um diagrama de pontos e linhas conectados aos pontos), respeitando a seguinte estrutura:

  1. Os nós representam dados ou entidade e bordas representam conexões entre nós; e
  2. As bordas são propriedades que podem estar relacionadas a nós, essa capacidade nos permite mostrar interações mais complexas e profundas entre os nossos dados.

Elementos básicos

A seguir destaco os elementos básicos que compõem a estrutura do SQL Graph Databases:

Node Table
Representa uma entidade em um esquema de grafos. Sempre que criamos uma tabela de nós, juntamente com as colunas definidas pelo usuário, uma coluna implícita $node _id é criada, o que identifica exclusivamente um determinado nó no banco de dados.

Os valores na coluna $node _id são gerados automaticamente e são uma combinação de object_id dessa tabela de nós e um valor bigint gerado internamente. No entanto, quando a coluna $node _id é selecionada, um valor calculado na forma de uma cadeia de caracteres JSON é exibido.
Além disso, $Node _id é uma coluna pseudo, que mapeia para um nome interno com String hex nele. Quando selecionamos $node _id da tabela, o nome da coluna aparecerá como $node _id_ hex_string.

É recomendável que os usuários criem uma restrição ou índice exclusivo na coluna $node _id no momento da criação da tabela de nós, mas se um não for criado, um índice padrão exclusivo não clusterizado será criado automaticamente.

Edge Table
Como mencionado anteriormente, uma tabela de borda(Edge Table) representa uma relação em um grafos. As bordas são sempre direcionadas e conectam dois nós.

Uma tabela de borda permite que os usuários modelem relacionamentos muitos-para-muitos no grafos, esta mesma tabela pode ou não ter quaisquer atributos definidos pelo usuário.

$Edge _id
A primeira coluna na tabela de borda representa $Edge _id que identifica exclusivamente uma aresta fornecida no banco de dados. O valor da coluna edge_id é gerado com a combinação de object_id da tabela de borda e um valor bigint gerado internamente.

No entanto, quando selecionamos a coluna $Edge _id, ela é exibida como a seqüência de caracteres JSON que é calculada a partir do valor da coluna.

$from _id
Coluna que armazena o $node _id do nó, de onde a borda é originada. Semelhante ao $Edge _id este é também um pseduo e pode ser usado como $from _id no entanto, o nome da coluna inclui Strings hex nele.

$to _id
Armazena o $node _id do nó, no qual a borda termina. Comportamento desta coluna em também como por $Edge _id e $from coluna _id.

Funções

Existem algumas funções adicionadas a linguagem Transact-SQL, que visam ajudar os usuários a extrair informações das colunas geradas. Abaixo estão as funções:

OBJECT_ID_FROM_NODE_ID: Função que permite extrair o object_id de um node_id. Precisamos passar node_id para esta função e ele retornará o object_id, também podemos obter o nome do objeto do object_id.

GRAPH_ID_FROM_NODE_ID: Função que permite extrair o GRAPH_ID de um node_id. Precisamos passar node_id para esta função e ele retornará o object_id.

NODE_ID_FROM_PARTS: Através desta função podemos construir um node_id de um object_id e um graph_id.

OBJECT_ID_FROM_EDGE_ID: Função utilizada para extrair um object_id de um EDGE_ID.

GRAPH_ID_FROM_EDGE_ID: Função utilizada para identificar um GRAPH_ID de EDGE_ID.

EDGE_ID_FROM_PARTS: Função que nos permite identificar o id utilizada entre as conexões de EDGE_ID de object_id e identidade.

Tabelas de Sistemas e Metadados

Sys.Tables – Novas colunas foram adicionadas ao sys.tables para identificar se uma tabela é um nó ou uma borda, conforme apresenta a Tabela 1 abaixo:

Column Name Data Type Description
is_node bit 1 = this is a node table
is_edge bit 1 = this is an edge table

Tabela 1 – Novas colunas adicionadas a system table sys.tables.

Sys.Columns – Novas colunas foram adicionadas ao sys.tables para indicar o tipo da coluna em tabelas de nó e borda, permitindo o relacionamento entre as systems tables sys.columns e sys.tables. A Tabela 2 abaixo apresenta a relação de novas colunas adicionadas a sys.columns:

Column Name Data Type Description
graph_type int Internal column with a set of values.

The values are between 1-8 for graph columns and NULL for others:

1 – GRAPH_ID
2 – GRAPH_ID_COMPUTED
3 – GRAPH_FROM_ID
4 – GRAPH_FROM_OBJ_ID
5 – GRAPH_FROM_ID_COMPUTED
6 – GRAPH_TO_ID
7 – GRAPH_TO_OBJ_ID
8 – GRAPH_TO_ID_COMPUTED

graph_type_desc nvarchar(60) internal column with a set of values

Tabela 2 – Novas colunas adicionadas a system table sys.columns.

Nossa, quanta coisa nova foi adicionado ao Microsoft SQL Server a partir desta nova funcionalidades, como também, diversas mudanças internadas como de costume também foram realizadas no produto afim de possibilitar o uso destas e outras funcionalidades, algo comumente realizado a cada nova versão.

Vamos então conhecer de forma prática o SQL Graph Databases e entender como estes elementos podem ser utilizados através do cenário que estaremos implementando a partir de agora.

Implementando o SQL Graph Databases

Se estamos nos referindo ao um banco de dados de grafos, nada melhor do que representar a estrutura que será utilizada em nosso cenário de exemplo através de um Diagrama conforme ilustra a Figura 2 abaixo:

Figura 2 – Diagrama – Estrutura utilizada para o exemplo.

Os nós são SQL Server, Azure e Windows e segue (bordas) fornecem conexões entre nós. Este modelo de banco de dados não pode ser tratado como uma alternativa a um modelo de banco de dados relacional, mas confrontados com alguns problemas específicos, o modelo de banco de dados em grafos pode ser alternativo e efetivo.

Observações: Se você olhar para o diagrama de perto, talvez você pode projetar este modelo de dados em um banco de dados relacional por junções, mas imagine que se você tiver um monte de nós e bordas, em seguida, quantas junções você vai precisar? Outra consideração importante se relaciona na forma de como este projeto funcionaria? Por esta razão, ao lidar com alguns problemas de negócios, precisamos de um banco de dados representado na teoria de grafos.

Um cenário muito interessante para a adoção de um banco de dados em grafos a ser considerado são meios de comunicação social. Por exemplo, há um monte de ações sociais, cada ação social cria uma marca. Quando combinamos estas marcas, parece uma teia de aranha. O modelo de banco de dados em grafos é ideal para armazenar esse tipo de dados.

Criando o ambiente

Para nossa prática vamos trabalhar com o seguinte ambiente:

  • Database – SQLGraphDatabase;
  • Node Table – Products; e
  • Edge Table – Microsoft.

Vamos começar criando nosso banco de dados e a node table através do Bloco de Código 1 apresentado na sequência:

— Bloco de Código 1 – Criando Banco de Dados e Node Table —

— Criando o Banco de Dados —
Create Database SQLGraphDatabases
Go

— Acessando o Banco de Dados —
Use SQLGraphDatabases
Go

— Criando a Node Table Products —
Create Table Products
(ProductID TinyInt Primary Key,
ProductName Varchar(100)
) As Node
Go

Note que instrução Create Table especificamos ao final da mesma a palavra chave Node, desta forma, o Microsoft SQL Server vai entender que nossa tabela será um nó e posteriormente estará relacionada com no mínimo uma borda.

O próximo passo é realizar a inserção de dados na tabela Products, para isso vamos utilizar o Bloco de Código 2 apresentado a seguir:

— Bloco de Código 2 – Inserindo dados na Node Table Products —

— Inserindo dados na Node Table Products —
Insert Into Products
Values (1,’SQL Server’),
(2,’Azure’),
(3,’Windows’)
Go

— Consultando os dados —
Select ProductId, ProductName from Products
Go

Você poderá notar que após a execução do comando Select teremos o resultado das três linhas de registros lógicos adicionadas a node table Products apresentados em tela, para que seja possível apresentar toda estrutura da tabela incluindo o $Node_Id, vamos então utilizar um simples e conhecido Select * (técnica não recomendável, mas para este cenário será útil para apresentar de maneira rápida a estrutura da node table Products).

— Apresentando toda estrutura da node table Products e seus respectivos dados —

Select * From Products
Go

A Figura 3 abaixo ilustra o retorno dos dados obtidos após a execução do Select acima:

Figura 3 – Estrutura da node table Products, incluindo $Node_ID e dados.

Continuando a nossa caminhada, vamos agora criar nossa tabela borda (edge table) denominada Microsoft, sendo esta o elemento utilizado para estabelecer as ligações entre os dados da node table para com a edge table, desta forma utilizaremos o Bloco de Código 3 apresentado a seguir:

— Bloco de Código 3 – Criando a Edge Table Microsoft —

— Criando a Edge Table Microsoft —
Create Table Microsoft As Edge
Go

— Consultando a estrutura da Edge Table Microsoft —
Select * from Microsoft
Go

Pronto nossa tabela borda esta criada, nosso penúltimo passo será adicionar os dados oriundos da node table Products, estabelecem assim as relações entre ambos os elementos, para tal procedimentos utilizaremos o Bloco de Código 4 apresentado a seguir:

— Bloco de Código 4 – Inserindo os dados na Edge Table Microsoft —

— Azure com SQL Server —
Insert Into Microsoft ($from_id , $to_id )
Values ((Select $node_id from Products where ProductId=2),
(Select $node_id from Products where ProductId=1))
Go

— Windows com SQL Server —
Insert Into Microsoft ($from_id ,$to_id )
Values ((Select $node_id from Products where ProductId=3),
(Select $node_id from Products where ProductId=1))
Go

— Windows com Azure —
Insert Into Microsoft ($from_id ,$to_id )
Values ((Select $node_id from Products where ProductId=3),
(Select $node_id from Products where ProductId=2))
Go

— Consultando os dados inseridos na Edge Table Microsoft —
Select * from Microsoft
Go

Muito bom, acabamos de estabelecer as ligações entre nossa node table e a edge table, note que para realizar este vinculo entre os dados oriundas da node table Products para a edge table Microsoft, utilizamos os valores da coluna ProductID existente na tabela de Products, como elemente chave a ser inserido nas colunas $from_id e $to_id no momento da criação da edge table Microsoft.

Figura 4 a seguir ilustra os dados inseridos na edge table Microsoft e apresentados no formato de string JSON:

Figura 4 – Dados inseridos na edge Table Microsoft.

Agora falta muito pouco e chegamos ao último passo que consiste justamente em identificar as conexões estabelecidas com base no Bloco de Código 4 processado anteriormente, onde através da nova função Match() em conjunto com seus operadores ‘-‘ ou ‘->’ podemos definir o caminho para encontrar os dados respeitando a estrutura de nós e bordas. Para tal procedimento executaremos o Bloco de Código 5 apresentado abaixo:

— Bloco de Código 5 – Identificando as conexões entre os dados —

— Utilizando a função Match(), encontrando as conexões do ProductName = Azure —
Select Concat(Products.ProductName,’ –> ‘, ProductsDetails.ProductName) As Connections
From Products, Microsoft, Products ProductsDetails
Where Match(Products-(Microsoft)->ProductsDetails)
And Products.ProductName = ‘Azure’
Go

— Utilizando a função Match(), encontrando as conexões do ProductName = Windows —
Select Concat(Products.ProductName,’ –> ‘, ProductsDetails.ProductName) As Connections
From Products, Microsoft, Products ProductsDetails
Where Match(Products-(Microsoft)->ProductsDetails)
And Products.ProductName = ‘Windows’
Go

Após a execução do Bloco de Código 5 apresentado anteriormente o Management Studio deverá retornar um resultado similar ao apresentado pela Figura 5 abaixo:

Figura 5 – Conexões de dados estabelecidas com base nas colunas $from_id  e $to_id.

Incrível, chegamos ao final de mais um post da sessão Dica do Mês, tenho a certeza que você gostou do conteúdo apresentado hoje neste post.

Vale ressaltar que alguns pontos não foram abordados neste post, dentre eles como utilizar um índice clusterizado ou não clusterizado, como também, a maneira que uma Node Table e Edge Table são apresentadas na estrutura de um banco de dados através do Management Studio.

No que diz respeito ao novo modelo de banco de dados, tenha a certeza que a minha missão foi cumprida, principalmente no entendimento de como esta uma nova forma de representação baseada em grafos poderá nos ajudar a estabelecer uma nova técnica de relacionamento entre nossas tabelas e seus respectivos dados, indo muito além dos tradicionais conceitos dentre eles: chaves primárias e estrangeiras, caminhando para uma nova proposta com base no conceito de relacionamento lógico de dados.

Antes de encerrarmos, gostaria de contar com a sua participação neste post, respondendo a enquete abaixo:


Referências

https://docs.microsoft.com/en-us/sql/relational-databases/graphs/sql-graph-sample

https://docs.microsoft.com/en-us/sql/relational-databases/graphs/sql-graph-architecture

https://docs.microsoft.com/en-us/sql/relational-databases/graphs/sql-graph-overview

https://www.red-gate.com/simple-talk/sql/sql-development/sql-server-graph-databases-part-1-introduction/

https://www.sqlshack.com/implement-graph-database-sql-server-2017/

https://www.mssqltips.com/sqlservertip/4883/sql-server-2017-graph-database-example/

 

Posts Anteriores

https://pedrogalvaojunior.wordpress.com/2018/01/24/dicadomes-sqlservertoolsuiteintroduction/

https://pedrogalvaojunior.wordpress.com/2017/11/01/dicadomessql2017novascolunasinternas/

https://pedrogalvaojunior.wordpress.com/2017/08/26/dica-do-mes-simulando-a-insercao-de-uma-massa-de-dados-aleatoria/

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

Conclusão

Neste post, conhecemos um pouco sobre este novo recursos SQL Graph Databases implementado a partir da versão 2017 do Microsoft SQL Server.

O SQL Server Graph é um recurso fantástico que nos permite implementar dentro da mesma estrutura de banco de dados existente no Microsoft SQL Server dois modelos de relacionamento de dados totalmente diferentes.  Através desta arquitetura híbrida temos a capacidade de utilizar recursos do mecanismo do SQL Server com um banco de dados na estrutura de grafos de maneira muito similar para não se dizer parecida com os recursos aplicados no modelo relacional, com base, na linguagem Transact-SQL nos dando todo suporte a consultas para este novo formato.

O banco de dados baseados na estrutura de grafos (SQL Graph Databases) apresentam como toda nova tecnologia algumas limitações técnicas neste momento, que tendem nas próximas versões do produto evoluírem ou até mesmo deixar de existir, algo que neste momento não podem ser consideradas limitações que impossibilitem a sua adoção ou uso em novos projetos de bancos de dados, como também, não se tornem  limitações a outros recursos excepcionais no existentes no Microsoft SQL Server 2017, mesmo assim podemos reconhecer que este novo modelo de banco de dados, pode ser considerada uma tecnologia convincente e promissora.

Agradecimentos

Agradeço a você por sua atenção e visita ao meu blog. Fique a vontade para enviar suas críticas, sugestões, observações e comentários.

Um forte abraço, nos encontramos no próximo post a ser publicado no mês de abril.

Viva o Microsoft SQL Server 2017 e suas novas funcionalidades…

Um forte abraço, sucesso e até o próximo post.

Anúncios

Dica do Mês – SQL Setup ToolSuite Introduction


Olá pessoal, muito boa tarde.

Tudo bem? Mais um dia de fortes chuvas aqui em São Roque e região, ainda bem que a internet até o presente  momento esta funcionando de forma razoável(é bom não elogiar muito)….

Estou retornado neste início de 2018 conforme prometido no último post da sessão Dica do Mês em 2017 com mais um post exclusivo desta sessão, daa mesma forma que o anterior apresentando algo diferente relacionado ao Microsoft SQL Server.

Neste post, quero compartilhar um conteúdo fresquinho que acabou de sair do forno, na verdade que acaba de ser liberado pelo time de engenheiros do Microsoft SQL Server dedicados exclusivamente ao suporte e desenvolvimento de soluções para o produto, conhecidos mundial como CSS SQL Server EngineersOfficial team Web Log for Microsoft Customer Service and Support (CSS) SQL Support. Caso você ainda não os conheça, não perca tempo acesse: https://blogs.msdn.microsoft.com/psssql/.

Continuando com o post, este fantástico time de profissionais mantidos pelo Microsoft esta a cada dia implementando novas soluções que nos permitem administrar, gerenciar e soluções problemas que o Microsoft SQL Server poderá apresentar em qualquer uma das atuais versões disponibilizadas nos últimos anos. Pensando justamente neste tipo de cenário o CSS SQL Server Engineers acabam de compartilhar uma nova suíte chamada de SQL Setup ToolSuite Introduction.

Ficou curioso em saber um pouco mais sobre esta nova suíte? Então vamos em frente, vou tentar matar a sua curiosidade. Sendo assim, seja bem vindo ao post – Dica do Mês – SQL Setup ToolSuite Introduction.

Você vai conhecer um pouco sobre esta suíte e suas ferramentas…


SQL Setup ToolSuite Introduction (1) – FixMissingMSI

Se você encontrou problemas de MSI/MSP armazenados em cache durante a instalação do SQL Server, você pode ter acessado o artigo: Como restaurar os arquivos de cache do Windows Installer ausentes e resolver problemas que ocorrem durante uma atualização do SQL Server. 

Pensando justamente neste cenário que o time do CSS desenvolveu esta ferramenta, sendo esta uma solução para contornar este tão frequente comportamento apresentado pelo setup de instalação do Microsoft SQL Server. A Figura 1 ilustra a tela da FixMissingMSI, clique na própria figura para realizar o download:Figura 1 – SQL Suíte ToolSetup Introduction – FixMissingMSI.

SQL Setup ToolSuite Introduction (2) – Product Browser

Através desta simples e prática ferramenta, temas a capacidade de obter informações sobre todos os produtos relacionados ao Microsoft SQL Server instalados em sua máquina, dentre elas local de instalação, patch, versão entre outras.

A Figura 2 abaixo ilustra a tela do Product Browser, clique na própria figura para realizar o download:

Figura 2 – SQL Suíte ToolSetup Introduction – Product Browser.

SQL Setup ToolSuite Introduction (3) – SQL Registry Viewer

Você pode querer saber quais chaves do registro serão adicionadas ao sistema para uma instalação do SQL Server. Se você usar alguma ferramenta de snapshot do registro para comparar a mudança de registros de janela antes e depois da instalação do SQL você vai encontrar há 40.000 ~ 60000 modificações acontecendo.

No entanto, se você estudar as modificações com cuidado você vai descobrir que a maioria deles não tem muito sentido, por exemplo, muitas modificações vão para HKLM\DRIVERS\DriverDatabase\DeviceIds\ entrada. As modificações mais interessantes são:

<>Installer related registry keys under
HKEY_CLASSES_ROOT\Installer and
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18

<>COM+ related,Like
Computer\HKEY_CLASSES_ROOT\CLSID
Computer\HKEY_CLASSES_ROOT\Interface
Computer\HKEY_CLASSES_ROOT\TypeLib

<> SQL specific
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server

<>Service
WOW6432Node

Agora com o SQL Registry Viewer, você poderá obter facilmente todo este conjunto de dados armazenados no registro do Windows, relacionados ao Microsoft SQL Server e seus componentes. A Figura 3 a seguir apresenta a tela desta excepcional ferramenta:

Figura 3 –  SQL Suíte ToolSetup Introduction – SQL Registry Viewer.

E ai gostou destas novas ferramentas que fazem parte da SQL Setup ToolSuite Introduction? Posso lhe dizer que gostei muito, já realizei o download e testei em minhas máquinas físicas e virtuais, mas vou confessar de todas elas a que eu mais gostei foi a SQL Registry Viewer. E você?

Quer deixar a sua opinião? Compartilhar a sua preferência?

Então vote na enquete abaixo escolhendo a ferramenta que mais você gostou e acredita que poderá lhe ajudar mais:

Sensacional, show, chegamos ao final de mais um post da sessão Dica do Mês, espero que você tenha gostado, com certeza estas novas ferramentas desenvolvidas pelo CSS SQL Server Engineers poderão lhe ajudar muito em suas atividades diárias.


Referências

https://blogs.msdn.microsoft.com/psssql/2018/01/24/sql-setup-toolsuite-introduction-1-fixmissingmsi/

https://blogs.msdn.microsoft.com/psssql/2018/01/24/sql-setup-toolsuite-introduction-2-product-browser/

https://blogs.msdn.microsoft.com/psssql/2018/01/24/sql-setup-toolsuite-introduction-3-sql-registry-viewer/

Posts Anteriores

https://pedrogalvaojunior.wordpress.com/2017/11/01/dicadomessql2017novascolunasinternas/

https://pedrogalvaojunior.wordpress.com/2017/08/26/dica-do-mes-simulando-a-insercao-de-uma-massa-de-dados-aleatoria/

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/

Conclusão

Falar, compartilhar informações, e um pouco do meu conhecimento sobre o Microsoft SQL Server é algo que me da um imensão prazer e satisfação. Mas saber que existe um time de profissionais focados diariamente na evolução, correções e melhorias do produto é um sentimento que faz a cada dia saber que tomei a decisão certa em meados do ano 2000, quando resolvi mudar totalmente a minha carreira e se dedicar exclusivamente a este produto e todo o seu conjunto de ferramentas, componentes, recursos e soluções.

Estas três novas ferramentas, são um pequeno pedaço existente do lado externo do Microsoft SQL Server que nos permite entender e analisar a grandeza do produto, não somente na sua capacidade de processamento e armazenamento de dados, mas sim no seu real tamanho, proporção de soluções e possibilidades de se contornar, corrigir e mitigar qualquer possibilidade de falha, perda de performance ou um simples erro durante o processo de instalação.

Foi pensando justamente neste cenário que estas novas ferramentas que formam a SQL Setup ToolSuite Introduction nos permite fazer, colentando informações de chaves de registro ou até mesmo identificar produtos instalados em nossas máquinas relacionados a o SQL Server.

Parece ser simples isso! Na verdade é algo muito além de um simples editor de texto para se montar uma query, é justamente um ambiente SGBD. Este é o universo do Microsoft SQL Server, criado a muito anos que esta sempre evoluindo, passando por transformações sem perder a sua essência.

Para os demais produtos que acreditam fazer o mesmo que ele, eu digo, sinto muito.

Agradecimentos

Quero deixar um agradecimento especial ao Team CSS SQL Server Engineers, profissionais do mais alto escalão e nível técnico, que a cada dia nos ajudam a conhecer e desvendar os diversos mistérios existentes nas versões e edições do Microsoft SQL Server.

Agora agradeço a você por sua atenção e visita ao meu blog. Fique a vontade para enviar suas críticas, sugestões, observações e comentários.

Um forte abraço, nos encontramos no próximo post a ser publicado no mês de março.

Vai SQL Server, Vai SQL Server…..

Sucesso e até mais.

Dica do Mês – Microsoft SQL Server 2017 – Relação de Novas colunas internas


Olá pessoal, bom dia.

Tudo bem? Preparado para um mês que esta se iniciando hoje? Se você me perguntar eu ainda não sei te responder pois acordei a pouco(kkkkkk).

Estou iniciando mais um post da sessão Dica do Mês, hoje algo um pouco diferente, não vou apresentar linhas de código, funcionalidades novas ou algo que conheci, muito menos ferramentas. Caso você venha a me perguntar. “Mas Galvão o que exatamente você esta planejando para hoje?”

A minha resposta é simples, vou compartilhar o que descobri de novo no Microsoft SQL Server 2017 que poderá lhe ajudar em momentos de análise de seus dados, bancos de dados e até mesmo do próprio servidor SQL Server. Parece ser algo de outro mundo mas não é, muito pelo contrário, algo que você facilmente poderá encontrar sem muito esforço.

Mas antes de falar do post, vamos destacar um pouco sobre o Microsoft SQL Server 2017. Acredito que você deva saber que no último mês de outubro, a Microsoft realizou mais um lançamento de uma nova versão do Microsoft SQL Server, estou me referindo a versão 2017. Por acaso você estão utilizando esta nova versão? Caso ainda não tenha feito, aproveite e faça agora mesmo acessando o link: https://www.microsoft.com/en-us/sql-server/sql-server-2017.

Se você, assim como eu realizou o download no mesmo dia do lançamento, ou seja, dia 02/10, pode ter um certo tempo para notar que a cada nova versão, o produto esta evoluindo, tanto no seu processo de instalação que realmente é fantástico e muito prático, como também, na quantidade de recursos, funcionalidades e componentes internos apresentados a partir desta da versão 2017.

Foi pensando neste cenário que o post da sessão Dica do Mês foi concebido, apresentar um pouco das novidades internas que o Microsoft SQL Server 2017 possuí em comparação com seus antecessores.

Sendo assim, seja bem vindo ao post – Dica do Mês – Microsoft SQL Server 2017 – Relação de Novas colunas internas.

Você vai descobrir o conjunto de novos dados técnicos catalogados pelo SQL Server 2017 seremos capazes de obter em real-time……


Introdução

Afim de mostrar o que de novo foi adicionado a partir da versão 2017, decidi identificar o que internamente existe de diferente que não tínhamos na versão 2016 ou anteriores, desta forma, escolhi fazer um comparativo entre a versão 2017 e a versão 2016 SP1, lançado no último mês de abril.

Foi idealizando este cenário, que fiz a simples escolha de utilizar uma velha conhecida system view denominada sys.all_columns presente a partir do Microsoft SQL Server desde a versão 2005. Tenho quase a certeza que você conhece esta system view! Ainda não, poxa vida, isso não é um pecado, mas é algo que talvez possa lhe ser útil.

Basicamente a sys.all_columns, como boa parte das visões de sistemas, apresentam um conjunto de dados técnicos catalogados pelo Microsoft SQL Server afim de ajudar internamente o funcionamento lógico e relacional do produto, mas também, como um guia para nós profissionais de bancos de dados, quanto temos a necessidade de analisar ou identificar dados técnicos, objetos, recursos ou funcionalidades oriundas do SQL Server.

Através desta DMV, temos a capacidade de obter a relação completa de colunas que formam nossos objetos e também os próprios objetos criados pelo SQL Server no processo da instalação ou durante nossas atividades, o que me permitiu identificar os novas colunas internas adicionadas na versão 2017 categorizadas da seguinte maneira:

  • Internal Tables;
  • InLine Table-Valued Function;
  • System Tables;
  • System Views; e
  • User Tables.

A seguir apresento a relação completa das novas colunas internadas adicionadas a partir do Microsoft SQL Server 2017:

Internal Tables

  • _trusted_assemblies.create_date
  • _trusted_assemblies.created_by
  • _trusted_assemblies.description
  • _trusted_assemblies.hash
  • plan_persist_query.query_flags
  • plan_persist_query_hints.batch_sql_handle
  • plan_persist_query_hints.comment
  • plan_persist_query_hints.context_settings_id
  • plan_persist_query_hints.last_query_hint_failure_reason
  • plan_persist_query_hints.object_id
  • plan_persist_query_hints.query_hash
  • plan_persist_query_hints.query_hint_failure_count
  • plan_persist_query_hints.query_hint_id
  • plan_persist_query_hints.query_hints_flags
  • plan_persist_query_hints.query_hints
  • plan_persist_query_hints.query_id
  • plan_persist_query_hints.query_param_type
  • plan_persist_query_hints.statement_sql_handle
  • plan_persist_query_template_parameterization.comment
  • plan_persist_query_template_parameterization.last_parameterization_failure_reason
  • plan_persist_query_template_parameterization.parameterization_failure_count
  • plan_persist_query_template_parameterization.query_param_type
  • plan_persist_query_template_parameterization.query_template_flags
  • plan_persist_query_template_parameterization.query_template_hash
  • plan_persist_query_template_parameterization.query_template_id
  • plan_persist_query_template_parameterization.query_template
  • plan_persist_query_text.query_template_hash
  • plan_persist_wait_stats.count_executions
  • plan_persist_wait_stats.execution_type
  • plan_persist_wait_stats.last_query_wait_time_ms
  • plan_persist_wait_stats.max_query_wait_time_ms
  • plan_persist_wait_stats.min_query_wait_time_ms
  • plan_persist_wait_stats.plan_id
  • plan_persist_wait_stats.runtime_stats_interval_id
  • plan_persist_wait_stats.sumsquare_query_wait_time_ms
  • plan_persist_wait_stats.total_query_wait_time_ms
  • plan_persist_wait_stats.wait_category
  • plan_persist_wait_stats.wait_stats_id

Inline table-valued functions

  • dm_db_log_info.database_id
  • dm_db_log_info.file_id
  • dm_db_log_info.vlf_active
  • dm_db_log_info.vlf_begin_offset
  • dm_db_log_info.vlf_create_lsn
  • dm_db_log_info.vlf_first_lsn
  • dm_db_log_info.vlf_parity
  • dm_db_log_info.vlf_sequence_number
  • dm_db_log_info.vlf_size_mb
  • dm_db_log_info.vlf_status
  • dm_db_log_stats.active_log_size_mb
  • dm_db_log_stats.active_vlf_count
  • dm_db_log_stats.current_vlf_sequence_number
  • dm_db_log_stats.current_vlf_size_mb
  • dm_db_log_stats.database_id
  • dm_db_log_stats.log_backup_lsn
  • dm_db_log_stats.log_backup_time
  • dm_db_log_stats.log_checkpoint_lsn
  • dm_db_log_stats.log_end_lsn
  • dm_db_log_stats.log_min_lsn
  • dm_db_log_stats.log_recovery_lsn
  • dm_db_log_stats.log_recovery_size_mb
  • dm_db_log_stats.log_since_last_checkpoint_mb
  • dm_db_log_stats.log_since_last_log_backup_mb
  • dm_db_log_stats.log_truncation_holdup_reason
  • dm_db_log_stats.recovery_model
  • dm_db_log_stats.recovery_vlf_count
  • dm_db_log_stats.total_log_size_mb
  • dm_db_log_stats.total_vlf_count
  • dm_os_enumerate_filesystem.creation_time
  • dm_os_enumerate_filesystem.file_or_directory_name
  • dm_os_enumerate_filesystem.full_filesystem_path
  • dm_os_enumerate_filesystem.has_integrity_stream
  • dm_os_enumerate_filesystem.is_directory
  • dm_os_enumerate_filesystem.is_hidden
  • dm_os_enumerate_filesystem.is_read_only
  • dm_os_enumerate_filesystem.is_sparse
  • dm_os_enumerate_filesystem.is_system
  • dm_os_enumerate_filesystem.is_temporary
  • dm_os_enumerate_filesystem.last_access_time
  • dm_os_enumerate_filesystem.last_write_time
  • dm_os_enumerate_filesystem.level
  • dm_os_enumerate_filesystem.parent_directory
  • dm_os_enumerate_filesystem.size_in_bytes
  • dm_os_file_exists.file_exists
  • dm_os_file_exists.file_is_a_directory
  • dm_os_file_exists.parent_directory_exists
  • dm_sql_referenced_entities.is_incomplete
  • fn_full_dblog.AllocUnitId
  • fn_full_dblog.AllocUnitName
  • fn_full_dblog.Article ID
  • fn_full_dblog.Begin Time
  • fn_full_dblog.Beginlog Status
  • fn_full_dblog.Bulk allocated extent count
  • fn_full_dblog.Bulk allocated extent ids
  • fn_full_dblog.Bulk allocation first IAM Page ID
  • fn_full_dblog.Bulk AllocUnitId
  • fn_full_dblog.Bulk RowsetId
  • fn_full_dblog.Byte Offset
  • fn_full_dblog.Bytes Freed
  • fn_full_dblog.Checkpoint Begin
  • fn_full_dblog.Checkpoint End
  • fn_full_dblog.CHKPT Begin DB Version
  • fn_full_dblog.CHKPT End DB Version
  • fn_full_dblog.CI Index Id
  • fn_full_dblog.CI Table Id
  • fn_full_dblog.Column Offset
  • fn_full_dblog.Command Type
  • fn_full_dblog.Command
  • fn_full_dblog.Compression Info
  • fn_full_dblog.Compression Log Type
  • fn_full_dblog.Context
  • fn_full_dblog.CopyVerionInfo Source Page Id
  • fn_full_dblog.CopyVerionInfo Source Page LSN
  • fn_full_dblog.CopyVerionInfo Source Slot Count
  • fn_full_dblog.CopyVerionInfo Source Slot Id
  • fn_full_dblog.Current LSN
  • fn_full_dblog.Database Name
  • fn_full_dblog.Description
  • fn_full_dblog.Dirty Pages
  • fn_full_dblog.End AGE
  • fn_full_dblog.End Time
  • fn_full_dblog.File ID
  • fn_full_dblog.File Status
  • fn_full_dblog.FileGroup ID
  • fn_full_dblog.Flag Bits
  • fn_full_dblog.Flags
  • fn_full_dblog.Format LSN
  • fn_full_dblog.InvalidateCache Id
  • fn_full_dblog.InvalidateCache keys
  • fn_full_dblog.Last Distributed Backup End LSN
  • fn_full_dblog.Last Distributed End LSN
  • fn_full_dblog.Lock Information
  • fn_full_dblog.Log Record Fixed Length
  • fn_full_dblog.Log Record Length
  • fn_full_dblog.Log Record
  • fn_full_dblog.Log Reserve
  • fn_full_dblog.LogBlockGeneration
  • fn_full_dblog.Logical Name
  • fn_full_dblog.LSN before writes
  • fn_full_dblog.Mark Name
  • fn_full_dblog.Master DBID
  • fn_full_dblog.Master XDESID
  • fn_full_dblog.Max XDESID
  • fn_full_dblog.Meta Status
  • fn_full_dblog.Minimum LSN
  • fn_full_dblog.Modify Size
  • fn_full_dblog.New Size
  • fn_full_dblog.New Split Page
  • fn_full_dblog.New Value
  • fn_full_dblog.NewAllocUnitId
  • fn_full_dblog.Next Replicated End LSN
  • fn_full_dblog.Num Elements
  • fn_full_dblog.Num Transactions
  • fn_full_dblog.Number of Locks
  • fn_full_dblog.Offset in Row
  • fn_full_dblog.Offset
  • fn_full_dblog.Old Size
  • fn_full_dblog.Old Value
  • fn_full_dblog.Oldest Active LSN
  • fn_full_dblog.Oldest Active Transaction ID
  • fn_full_dblog.Oldest Replicated Begin LSN
  • fn_full_dblog.Operation
  • fn_full_dblog.Page ID
  • fn_full_dblog.PageFormat FormatOption
  • fn_full_dblog.PageFormat PageFlags
  • fn_full_dblog.PageFormat PageLevel
  • fn_full_dblog.PageFormat PageStat
  • fn_full_dblog.PageFormat PageType
  • fn_full_dblog.Pages Written
  • fn_full_dblog.Parent Transaction ID
  • fn_full_dblog.Partial Status
  • fn_full_dblog.PartitionId
  • fn_full_dblog.Physical Name
  • fn_full_dblog.Prepare Time
  • fn_full_dblog.Preplog Begin LSN
  • fn_full_dblog.Previous LSN
  • fn_full_dblog.Previous Page LSN
  • fn_full_dblog.Previous Savepoint
  • fn_full_dblog.Publication ID
  • fn_full_dblog.Repl CSN
  • fn_full_dblog.Repl Epoch
  • fn_full_dblog.Repl Flags
  • fn_full_dblog.Repl Min Hold LSN
  • fn_full_dblog.Repl Msg
  • fn_full_dblog.Repl Partition ID
  • fn_full_dblog.Repl Source Commit Time
  • fn_full_dblog.Replicated Records
  • fn_full_dblog.Rowbits Bit Count
  • fn_full_dblog.Rowbits Bit Value
  • fn_full_dblog.Rowbits First Bit
  • fn_full_dblog.RowFlags
  • fn_full_dblog.RowLog Contents 0
  • fn_full_dblog.RowLog Contents 1
  • fn_full_dblog.RowLog Contents 2
  • fn_full_dblog.RowLog Contents 3
  • fn_full_dblog.RowLog Contents 4
  • fn_full_dblog.RowLog Contents 5
  • fn_full_dblog.Rows Deleted
  • fn_full_dblog.RowsetId
  • fn_full_dblog.Savepoint Name
  • fn_full_dblog.Server Name
  • fn_full_dblog.Server UID
  • fn_full_dblog.Slot ID
  • fn_full_dblog.SPID
  • fn_full_dblog.Tag Bits
  • fn_full_dblog.Text Size
  • fn_full_dblog.TextPtr
  • fn_full_dblog.Transaction Begin
  • fn_full_dblog.Transaction ID
  • fn_full_dblog.Transaction Name
  • fn_full_dblog.Transaction SID
  • fn_full_dblog.Virtual Clock
  • fn_full_dblog.VLFs added
  • fn_full_dblog.Xact ID
  • fn_full_dblog.Xact Node ID
  • fn_full_dblog.Xact Node Local ID
  • fn_full_dblog.Xact Type
  • fn_get_audit_file.affected_rows
  • fn_get_audit_file.application_name
  • fn_get_audit_file.client_ip
  • fn_get_audit_file.duration_milliseconds
  • fn_get_audit_file.response_rows
  • fn_xe_file_target_read_file.timestamp_utc

System Tables

  • syscscolsegments.container_id
  • syscsdictionaries.container_id

User Tables

  • MSreplication_options.install_failures
  • MSreplication_options.major_version
  • MSreplication_options.minor_version
  • MSreplication_options.optname
  • MSreplication_options.revision
  • MSreplication_options.value
  • spt_monitor.connections
  • spt_monitor.cpu_busy
  • spt_monitor.idle
  • spt_monitor.io_busy
  • spt_monitor.lastrun
  • spt_monitor.pack_errors
  • spt_monitor.pack_received
  • spt_monitor.pack_sent
  • spt_monitor.total_errors
  • spt_monitor.total_read
  • spt_monitor.total_write

Views

  • all_columns.graph_type_desc
  • all_columns.graph_type
  • availability_groups.cluster_type_desc
  • availability_groups.cluster_type
  • availability_groups.required_synchronized_secondaries_to_commit
  • availability_groups.sequence_number
  • columns.graph_type_desc
  • columns.graph_type
  • computed_columns.graph_type_desc
  • computed_columns.graph_type
  • database_automatic_tuning_mode.actual_state_desc
  • database_automatic_tuning_mode.actual_state
  • database_automatic_tuning_mode.desired_state_desc
  • database_automatic_tuning_mode.desired_state
  • database_automatic_tuning_options.actual_state_desc
  • database_automatic_tuning_options.actual_state
  • database_automatic_tuning_options.desired_state_desc
  • database_automatic_tuning_options.desired_state
  • database_automatic_tuning_options.name
  • database_automatic_tuning_options.reason_desc
  • database_automatic_tuning_options.reason
  • database_credentials.principal_id
  • database_files.is_persistent_log_buffer
  • database_query_store_options.wait_stats_capture_mode_desc
  • database_query_store_options.wait_stats_capture_mode
  • database_scoped_configurations.is_value_default
  • database_scoped_credentials.principal_id
  • databases.is_temporal_history_retention_enabled
  • dm_db_column_store_row_group_physical_stats.closed_time
  • dm_db_column_store_row_group_physical_stats.created_time
  • dm_db_column_store_row_group_physical_stats.deleted_rows
  • dm_db_column_store_row_group_physical_stats.delta_store_hobt_id
  • dm_db_column_store_row_group_physical_stats.generation
  • dm_db_column_store_row_group_physical_stats.has_vertipaq_optimization
  • dm_db_column_store_row_group_physical_stats.index_id
  • dm_db_column_store_row_group_physical_stats.object_id
  • dm_db_column_store_row_group_physical_stats.partition_number
  • dm_db_column_store_row_group_physical_stats.row_group_id
  • dm_db_column_store_row_group_physical_stats.size_in_bytes
  • dm_db_column_store_row_group_physical_stats.state_desc
  • dm_db_column_store_row_group_physical_stats.state
  • dm_db_column_store_row_group_physical_stats.total_rows
  • dm_db_column_store_row_group_physical_stats.transition_to_compressed_state_desc
  • dm_db_column_store_row_group_physical_stats.transition_to_compressed_state
  • dm_db_column_store_row_group_physical_stats.trim_reason_desc
  • dm_db_column_store_row_group_physical_stats.trim_reason
  • dm_db_file_space_usage.modified_extent_page_count
  • dm_db_mirroring_connections.address
  • dm_db_tuning_recommendations.details
  • dm_db_tuning_recommendations.execute_action_duration
  • dm_db_tuning_recommendations.execute_action_initiated_by
  • dm_db_tuning_recommendations.execute_action_initiated_time
  • dm_db_tuning_recommendations.execute_action_start_time
  • dm_db_tuning_recommendations.is_executable_action
  • dm_db_tuning_recommendations.is_revertable_action
  • dm_db_tuning_recommendations.last_refresh
  • dm_db_tuning_recommendations.name
  • dm_db_tuning_recommendations.reason
  • dm_db_tuning_recommendations.revert_action_duration
  • dm_db_tuning_recommendations.revert_action_initiated_by
  • dm_db_tuning_recommendations.revert_action_initiated_time
  • dm_db_tuning_recommendations.revert_action_start_time
  • dm_db_tuning_recommendations.score
  • dm_db_tuning_recommendations.state
  • dm_db_tuning_recommendations.type
  • dm_db_tuning_recommendations.valid_since
  • dm_db_xtp_checkpoint_internals.checkpoint_id
  • dm_db_xtp_checkpoint_internals.checkpoint_timestamp
  • dm_db_xtp_checkpoint_internals.is_synchronized
  • dm_db_xtp_checkpoint_internals.last_segment_lsn
  • dm_db_xtp_checkpoint_internals.recovery_lsn
  • dm_exec_query_stats.last_columnstore_segment_reads
  • dm_exec_query_stats.last_columnstore_segment_skips
  • dm_exec_query_stats.max_columnstore_segment_reads
  • dm_exec_query_stats.max_columnstore_segment_skips
  • dm_exec_query_stats.min_columnstore_segment_reads
  • dm_exec_query_stats.min_columnstore_segment_skips
  • dm_exec_query_stats.total_columnstore_segment_reads
  • dm_exec_query_stats.total_columnstore_segment_skips
  • dm_exec_requests.is_resumable
  • dm_os_enumerate_fixed_drives.drive_type_desc
  • dm_os_enumerate_fixed_drives.drive_type
  • dm_os_enumerate_fixed_drives.fixed_drive_path
  • dm_os_enumerate_fixed_drives.free_space_in_bytes
  • dm_os_host_info.host_distribution
  • dm_os_host_info.host_platform
  • dm_os_host_info.host_release
  • dm_os_host_info.host_service_pack_level
  • dm_os_host_info.host_sku
  • dm_os_host_info.os_language_version
  • dm_os_memory_objects.partition_type_desc
  • dm_os_nodes.cpu_count
  • dm_os_sys_info.cores_per_socket
  • dm_os_sys_info.numa_node_count
  • dm_os_sys_info.process_physical_affinity
  • dm_os_sys_info.socket_count
  • dm_os_worker_local_storage.gq_address
  • dm_tran_global_transactions.max_csn
  • dm_tran_global_transactions_enlistments.snapshot_timestamp
  • dm_tran_global_transactions_log.commit_timestamp
  • dm_tran_version_store_space_usage.database_id
  • dm_tran_version_store_space_usage.reserved_page_count
  • dm_tran_version_store_space_usage.reserved_space_kb
  • dm_xe_session_targets.bytes_written
  • dm_xe_sessions.buffer_full_count
  • dm_xe_sessions.buffer_processed_count
  • dm_xe_sessions.total_bytes_generated
  • external_libraries.external_library_id
  • external_libraries.language
  • external_libraries.name
  • external_libraries.principal_id
  • external_libraries.scope_desc
  • external_libraries.scope
  • external_library_files.content
  • external_library_files.external_library_id
  • external_library_files.platform_desc
  • external_library_files.platform
  • hash_indexes.auto_created
  • hash_indexes.is_ignored_in_optimization
  • identity_columns.graph_type_desc
  • identity_columns.graph_type
  • index_resumable_operations.index_id
  • index_resumable_operations.last_max_dop_used
  • index_resumable_operations.last_pause_time
  • index_resumable_operations.name
  • index_resumable_operations.object_id
  • index_resumable_operations.page_count
  • index_resumable_operations.partition_number
  • index_resumable_operations.percent_complete
  • index_resumable_operations.sql_text
  • index_resumable_operations.start_time
  • index_resumable_operations.state_desc
  • index_resumable_operations.state
  • index_resumable_operations.total_execution_time
  • indexes.auto_created
  • indexes.is_ignored_in_optimization
  • indexes.suppress_dup_key_messages
  • key_constraints.is_enforced
  • masked_columns.graph_type_desc
  • masked_columns.graph_type
  • master_files.is_persistent_log_buffer
  • query_store_plan.plan_forcing_type_desc
  • query_store_plan.plan_forcing_type
  • query_store_runtime_stats.avg_log_bytes_used
  • query_store_runtime_stats.avg_num_physical_io_reads
  • query_store_runtime_stats.avg_tempdb_space_used
  • query_store_runtime_stats.last_log_bytes_used
  • query_store_runtime_stats.last_num_physical_io_reads
  • query_store_runtime_stats.last_tempdb_space_used
  • query_store_runtime_stats.max_log_bytes_used
  • query_store_runtime_stats.max_num_physical_io_reads
  • query_store_runtime_stats.max_tempdb_space_used
  • query_store_runtime_stats.min_log_bytes_used
  • query_store_runtime_stats.min_num_physical_io_reads
  • query_store_runtime_stats.min_tempdb_space_used
  • query_store_runtime_stats.stdev_log_bytes_used
  • query_store_runtime_stats.stdev_num_physical_io_reads
  • query_store_runtime_stats.stdev_tempdb_space_used
  • query_store_wait_stats.avg_query_wait_time_ms
  • query_store_wait_stats.execution_type_desc
  • query_store_wait_stats.execution_type
  • query_store_wait_stats.last_query_wait_time_ms
  • query_store_wait_stats.max_query_wait_time_ms
  • query_store_wait_stats.min_query_wait_time_ms
  • query_store_wait_stats.plan_id
  • query_store_wait_stats.runtime_stats_interval_id
  • query_store_wait_stats.stdev_query_wait_time_ms
  • query_store_wait_stats.total_query_wait_time_ms
  • query_store_wait_stats.wait_category_desc
  • query_store_wait_stats.wait_category
  • query_store_wait_stats.wait_stats_id
  • sequences.last_used_value
  • spatial_indexes.auto_created
  • spatial_indexes.is_ignored_in_optimization
  • spt_values.high
  • spt_values.low
  • spt_values.name
  • spt_values.number
  • spt_values.status
  • spt_values.type
  • syscscontainers.blob_container_id
  • syscscontainers.blob_container_type
  • syscscontainers.blob_container_url
  • system_columns.graph_type_desc
  • system_columns.graph_type
  • tables.history_retention_period_unit_desc
  • tables.history_retention_period_unit
  • tables.history_retention_period
  • tables.is_edge
  • tables.is_node
  • trusted_assemblies.create_date
  • trusted_assemblies.created_by
  • trusted_assemblies.description
  • trusted_assemblies.hash
  • xml_indexes.auto_created
  • xml_indexes.is_ignored_in_optimization

Importante: Vale ressaltar que estas novas colunas estão compondo o conjunto atual de recursos internos já existentes no Microsoft SQL Server, não estou me referindo a novas Internal Tables, DMVs ou Views adicionadas ao produto na versão 2017.

Com isso chegamos ao final de mais um post da sessão Dica do Mês, espero que você tenha gostado, então do meu tradicional encerramento, quero destacar em algumas destas novas colunas serão destaco em posts futuros do meu blog.


Referências

https://technet.microsoft.com/pt-br/library/ms178596(v=sql.110).aspx

https://technet.microsoft.com/pt-br/library/ms188021(v=sql.110).aspx

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

Posts Anteriores

https://pedrogalvaojunior.wordpress.com/2017/08/26/dica-do-mes-simulando-a-insercao-de-uma-massa-de-dados-aleatoria/

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/

Conclusão

A cada versão do Microsoft SQL Server evolui, a gama de dados técnicos catalogados que nos permitem analisar e ajudar em possíveis cenários de administração ou tomadas de decisão cresce de forma exponencial, com isso, temos um conjunto inimaginável de possibilidades e alternativas que nos possibilitam superior nossos desafios.

Esse é o Microsoft SQL Server ainda mais poderoso na versão 2017.

 

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 no próximo post a ser publicado no mês de janeiro de 2018.

Vai SQL Server, Vai SQL Server…..

Abraços.

Dica do Mês – Simulando a inserção de uma massa de dados aleatória


Olá pessoal, boa tarde.

Estou retornando com mais um post da sessão Dica do Mês, onde hoje vou compartilhar algo que poderá lhe ajudar de maneira simples e direta em suas atividades relacionadas a simulação de manipulação de dados no Microsoft SQL Server.

Acredito que em algum momento você já teve a necessidade de inserir dezenas, centenas ou até mesmo milhares de linhas em uma determinada tabela em seus bancos de dados, se você ainda não passou por esta necessidade pode ter a certeza que em algum momento isso poderá lhe acontecer.

Pensando justamente nisso, vou compartilhar no post de hoje um script de minha autoria que utilizo justamente para realizar esta inserção de dados aleatórios em uma tabela específica sem levar em consideração a qualidade e veracidade dos dados, como também regras de integridade referencial ou normalização.

Sendo assim, seja bem vindo ao post – Dica do Mês – Simulando a inserção de uma massa de dados aleatória.

Bom divertimento……


Introdução

A necessidade de se trabalhar com um volume considerável de dados pode ser algo bastante comum para muitos profissionais de bancos de dados, para outros nem tanto.

Este pode parecer um cenário bastante complexo, que venha a exigir um grande conhecimento técnico ou até mesmo o uso de ferramentas de terceiros para tal finalidade. Mas na sua grande maioria os recursos existentes no próprio Microsoft SQL Server nos permite criar scripts ou blocos de códigos capazes de realizar tão procedimento sem requerer a obtenção ou exigência de um alto nível de conhecimento.

Nosso Cenário

Afim de tentar ilustrar como podemos realizar este tipo de procedimento em um ambiente de banco de dados, vamos trabalhar com um ambiente de banco de dados bastante simples e que apresenta baixa complexidade.

Nosso ambiente será forma por uma única tabela denominada MassaDeDados, composta pela seguinte estrutura de colunas:

  • Codigo;
  • ClienteID;
  • VendedorID;
  • Quantidade;
  • Valor; e
  • Data

A coluna denominada Codigo será definida como nossa coluna chave primária artificial numerada de forma sequência próprio SQL Server, tento como finalidade evitar a duplicação de registros e principalmente ser utilizada como atributo de busca e pesquisa de nossos dados. As demais colunas estarão sendo utilizadas como atributos complementares para ilustrar a capacidade de geração de dados aleatórios e posteriormente inseridos em nossa tabela MassaDeDados.

A seguir apresento o Bloco de Código 1, utilizado para criação da tabela MassaDeDados:

— Bloco de Código 1 —

Create Table MassaDeDados
(Codigo int IDENTITY(1,1) NOT NULL Primary Key,
ClienteId int NOT NULL,
VendedorId varchar(10) NOT NULL,
Quantidade smallint NOT NULL,
Valor numeric(18, 2) NOT NULL,
Data date NOT NULL)
Go

Perfeito, note que este bloco de código é bastante simples, nosso próximo passo será justamente trabalhar com o bloco de código que nos permitirá gerar o volume de dados aleatórios inseridos na sequência dentro da tabela MassaDeDados, para tal procedimentos vamos utilizar o Bloco de Código 2 apresentado abaixo:

— Bloco de Código 2 —

Declare @Texto Char(130), @Posicao TinyInt, @ContadorLinhas Int

Set @Texto = ‘0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ\_abcdefghijklmnopqrstuvwxyzŽŸ¡ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝàáâãäåæçèéêëìíîïðñòóôõöùúûüýÿ’ — Existem 130 caracteres neste texto —

Set @ContadorLinhas = Rand()*100000 — Definir a quantidade de linhas para serem inseridas —

While (@ContadorLinhas >=1)
Begin

Set @Posicao=Rand()*130

 

If @Posicao <=125
Begin
Insert Into MassaDeDados (ClienteId, VendedorId, Quantidade, Valor, Data)
Values(@ContadorLinhas,
Concat(SubString(@Texto,@Posicao+2,2),SubString(@Texto,@Posicao-4,4),SubString(@Texto,@Posicao+2,4)),
Rand()*1000,
Rand()*100+5,
DATEADD(d, 1000*Rand() ,GetDate()))

End
Else
Begin
Insert Into MassaDeDados (ClienteID, VendedorID, Quantidade, Valor, Data)
Values(@ContadorLinhas,
Concat(SubString(@Texto,@Posicao-10,1),SubString    (@Texto,@Posicao+4,6),SubString(@Texto,@Posicao-12,3)),
Rand()*1000,
Rand()*100+5,
DATEADD(d, 1000*Rand() ,GetDate()))

End

Set @ContadorLinhas = @ContadorLinhas – 1
End

Observação: Note que estou utilizando a função Concat() para realizar a concatenação dos dados sem a necessidade de conversão implícita, sendo esta função recurso adicionado a partir da versão 2012 do SQL Server, caso você esteja utilizando uma versão anterior remova a função Concat() e aplique a concatenação utilizando o operador de soma.

Agora basta executar o bloco de código e verificar o resultado obtido, no meu caso após a execução deste mesmo exemplo obtive o resultado apresentado pela Figura 1 apresentada abaixo:

Figura 1 – Massa de Dados aleatórios inseridos na tabela MassaDeDados.

Observando a Figura 1, torna-se fácil analisar o conjunto de dados aleatórios inseridos em cada coluna de nossa tabela, como também, a quantidade de linhas inseridas sendo um total de 41.857 linhas de registros.

Inicialmente o tamanho do bloco de código poderá parecer complexo ou até mesmo confuso, mas na verdade não é bem assim, o grande segredo esta justamente no uso da variável @Texto que apresenta um conjunto de 130 caracteres que podemos utilizar no processo de geração do nosso volume aleatório de dados.

Outro fator muito importante é o uso da função RAND() que nos possibilidade o sorteio de números decimais, algo que ajuda bastante quando queremos trabalhar com faixas de valores distintos.

Vale ressaltar que a função RAND trabalhar com valores decimais, para que seja possível realizar o sorteio aleatório de números e depois transformar em números inteiros temos a necessidade de utilizar variáveis que trabalhem com tipos de dados inteiros, neste caso: TinyInt, SmallInt, Int ou BigInt, caso contrário os valores retornados por esta função será sempre tratados e apresentados no formato de números decimais.

Com isso chegamos ao final de mais um post da sessão Dica do Mês, espero que você tenha gostado.

Referências

https://technet.microsoft.com/pt-br/library/ms177610(v=sql.105).aspx

https://docs.microsoft.com/en-us/sql/t-sql/data-types/data-types-transact-sql

https://docs.microsoft.com/en-us/sql/t-sql/language-elements/declare-local-variable-transact-sql

https://technet.microsoft.com/pt-br/library/hh231515(v=sql.110).aspx

Posts 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/

Conclusão

Em diversos cenários temos a necessidade de imaginar diversas possibilidades para se obter a solução de um problema que inicialmente se apresenta com algo de outro mundo, por outro lado realizando uma análise com calma e simulando diversos cenários esta possível solução tão “misteriosa” e “complexa” pode estar na frente de nossos olhos.

No post de hoje isso não foi diferente, realizar a inserção de um volume aleatório e fictício de dados dentro do Microsoft SQL Server pode ser feito de forma bastante simples e prática, sem requerer qualquer tipo ferramentas adicionais ou conhecimento de alto nível.

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 no próximo post a ser publicado no mês de outubro.

Valeu….

Dica do Mês – Conhecendo e aplicando o uso de atualização de estatísticas incrementais


Muito boa tarde pessoal, salve, salve comunidade e amantes de banco de dados.

Tudo bem com vocês? Estou aqui mais uma vez em um novo post do meu blog na sessão Dica do Mês, hoje falando de um assunto que até alguns dias atrás eu sinceramente nunca havia feito uso, mas com base em um post publicado do Ahmad Yaseen no MSSQLTips.com, acabou me servindo como fonte de inspiração para elaborar e compartilhar este post com vocês.

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.

Dando continuidade, vamos conhecer um recurso adicionado na versão 2014 do Microsoft SQL Server a partir do Service Pack 2 e mantido no Microsoft SQL Server 2016 SP1 conhecido como Estatísticas Incrementais ou Incremental Statistics, pode parecer estranho o nome, mas é exatamente isso que este recurso permite, realizar o processo de atualização de estatísticas de maneira incremental, ou para muitos incrementar o processo de atualização de estatísticas aplicadas aos nossos bancos de dados e seus respectivos objetos.

Parece ser coisa de louco isso, mas posso garantir que não é, absolutamente é algo totalmente viável e aplicável a qualquer ambiente que se faça uso do Microsoft SQL Server em conjunto com as funções e scheme de particionamento de dados.

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 – Conhecendo e aplicando o uso de atualização de estatísticas incrementais.

Seguindo….


Introdução

O otimizador de consultas do Microsoft SQL Server depende fortemente das estatísticas na geração a execução de plano de consulta mais eficiente. Estas estatísticas fornecem ao otimizador a distribuição dos valores de colunas na tabela e o número de linhas, também chamada a cardinalidade que resultará da consulta.

A ausência destas estatísticas, ou a existência de estatísticas desatualizadas, proporciona a ocorrência de querys consideradas lentas, neste sentido, o otimizador de consulta “query optimizer” acaba sendo obrigado a utilizar estatísticas imprecisas para criar o plano de execução, que pode ser considerado um plano não ideal para executar a consulta neste caso.

O SQL Server geralmente faz o seu trabalho em manter estas estatísticas atualizadas, mas como um administrador de banco de dados, você deve fazer seu trabalho, em alguns casos, atualizando as estatísticas manualmente. Atualizar estatísticas manualmente em tabelas grandes pode ser como um grande desafio, bem como, em tabelas pequenas pode-se imaginar que a estatística já esteja atualizada, o que em alguns cenários isso acaba não ocorrendo.

Um dos cenários mais impactados pelo uso de estatísticas desatualizadas ou atualizadas parcialmente são as tabelas particionadas. Como destacado anteriormente através do uso das funções de particionamento de dados introduzido no Microsoft SQL Server 2008, temos a capacidade de distribuir nossos dados em partições “pequenos fatias de armazenamento de dados” que nos possibilitar distribuir respectivos valores com base em uma função que análise e identifica o local de armazenamento do mesmo.

Para este tipo de ambiente, o uso de estatísticas como mecanismo para auxiliar no obtenção mais rápida do dado, pode apresentar simultaneamente o papel de herói como também de vilão, isso pode parecer meio confusão, mas não é! Basicamente quando trabalhamos com estatísticas acreditamos que sempre teremos todas as informações armazenados no histograma atualizadas de forma automática de maneira mais precisa possível, algo que não acontece exatamente desta maneira quando trabalhando com particionamento de dados.

Uma das situações mais comuns quando se uso particionamento de dados é a possibilidade de ocorrer a atualização de estatísticas de maneira parcial, ou seja, apena um partição de todo estrutura de partições acaba tendo suas informações de estatísticas atualizadas, o que poderá provocar uma alteração no plano de execução ou a possibilidade de criação de um plano incoerente.

Sabendo desta possibilidade e comportamento, o time de engenheiros e desenvolvedores do Microsoft SQL Server, implementou a partir da versão 2014 SP1 as Estatísticas Incrementais, funcionalidade que nos permite justamente contornar este tipo de situação.

Estatísticas Incrementais – Incremental Statistics

As estatísticas Incrementais, ajudam na atualização de estatísticas para apenas a partição ou partições que você escolher. Em vez de analisar e varrer a tabela inteira para atualizar as estatísticas, a partição selecionada será verificada somente para a atualização, reduzindo o tempo necessário para executar a operação de atualização de estatísticas, atualizando-se apenas a partição modificada.

O outro ponto importante é que a porcentagem de alterações de dados necessário para acionar a atualização automática de estatísticas, sendo este o valor 20% de linhas alteradas, o que proporcionará o uso de atualização de estatísticas no nível da partição, comportamento que não era permitido anteriormente.

Muito legal este novo recurso e principalmente o comportamento do Microsoft SQL Server, agora que já conhecemos conceitualmente como as estatísticas incrementais funcionam, chegou a hora de colocar as mãos no teclado e começar a conhecer de maneira prática esta funcionalidade.

Preparando o ambiente

Para entender a atualizar as estatísticas incrementais, vamos preparar um banco de dados de teste com uma tabela particionada. Começamos com a criação de um novo banco de dados denominado IncrementalStatistics, formado por quatro novos grupos de arquivos além de grupo de arquivos primário padrão, para tal vamos utilizar o Bloco de Código 1 apresentado a seguir:

— Bloco de Código 1 —

— Criando o Banco de Dados IncrementalStatistics —
Create Database IncrementalStatistics
Go
— Adicionando os Filegroups —
Alter Database IncrementalStatistics
Add Filegroup IncrementalStatisticsGrupo1
Go
Alter Database IncrementalStatistics
Add Filegroup IncrementalStatisticsGrupo2
Go
Alter Database IncrementalStatistics
Add Filegroup IncrementalStatisticsGrupo3
Go
Alter Database IncrementalStatistics
Add Filegroup IncrementalStatisticsGrupo4
Go

 

— Adicionando os Arquivos aos seus respectivos Filegroups —

Alter Database IncrementalStatistics
Add File (Name = N’IncrementalStatisticsGrupo1′,
FileName = N’S:\MSSQL-2016\Data\Arquivo-Grupo1-Data.ndf’,
Size = 4096KB,
FileGrowth =1024KB) To Filegroup IncrementalStatisticsGrupo1
Go

Alter Database IncrementalStatistics
Add File (Name = N’IncrementalStatisticsGrupo2′,
FileName = N’S:\MSSQL-2016\Data\Arquivo-Grupo2-Data.ndf’,
Size = 4096KB,
FileGrowth =1024KB) To Filegroup IncrementalStatisticsGrupo2
Go

Alter Database IncrementalStatistics
Add File (Name = N’IncrementalStatisticsGrupo3′,
FileName = N’S:\MSSQL-2016\Data\Arquivo-Grupo3-Data.ndf’,
Size = 4096KB,
FileGrowth =1024KB) To Filegroup IncrementalStatisticsGrupo3
Go

Alter Database IncrementalStatistics
Add File (Name = N’IncrementalStatisticsGrupo4′,
FileName = N’S:\MSSQL-2016\Data\Arquivo-Grupo4-Data.ndf’,
Size = 4096KB,
FileGrowth =1024KB) To Filegroup IncrementalStatisticsGrupo4
Go

Uma vez que o banco de dados é criado com os novos grupos de arquivos e arquivos de dados, precisamos prepará-lo para hospedar a tabela particionada. Nosso próximo passo consiste na criação da função particionada PartitionFunctionIncrementalStatistics que classifica os dados de acordo com os quatro trimestres do ano, sendo assim, vamos utilizar o Bloco de Código 2 apresentado abaixo:

— Bloco de Código 2 —

— Criando a Partition Function PartitionFunctionIncrementalStatistics —
USE IncrementalStatistics
GO

CREATE PARTITION FUNCTION PartitionFunctionIncrementalStatistics (Int)
AS
RANGE RIGHT FOR VALUES
(20171, 20172, 20173, 20174)
Go

Note que nossa PartitionFunctionIncrementalStatistics é composta por quatro partições de valores subdivididos da seguinte forma: 

  • 20171 – Valor que representa o Primeiro Quartil;
  • 20172 – Valor que representa o Segundo Quartil;
  • 20173 – Valor que representa o Terceiro Quartil do Ano; e
  • 20174 – Valor que representa o Quarto Quartil do Ano.

    Talvez você ainda não esteja entendendo o porque estamos fazendo uso deste tipo de implementação, tenha calma no decorrer do post tudo vai ficar mais claro e você terá total noção do porquê estamos utilizando este recurso.

Continuando com a nossa longa caminhada, você deve saber que para se trabalhar com particionamento de dados devemos além de criar uma Partition Function devemos obrigatoriamente criar um Partition Scheme,  que estará vinculado lógicamente a nossa partition function, sendo assim, este é nosso próximo passo, fazendo uso do Bloco de Código 3:

— Bloco de Código 3 —

— Criando o Partition Scheme PartitionSchemeIncrementalStatistics —
CREATE PARTITION SCHEME PartitionSchemeIncrementalStatistics AS
PARTITION PartitionFunctionIncrementalStatistics
TO
(
IncrementalStatisticsGrupo1,
IncrementalStatisticsGrupo2,
IncrementalStatisticsGrupo3,
IncrementalStatisticsGrupo4,
[PRIMARY])
Go

Esta quase tudo pronto para nossa brincadeira, seguiremos com a criação na nossa tabela TableIncrementalStatistics, este é um ponto importante do nosso ambiente, onde estamos fazendo uso da tabela particionada para ilustrar como as estatísticas incrementais vão realizar o seu papel.

TableIncrementalStatistics será composta por algumas colunas, dentre as quais a coluna Quartil, responsável em armazenar o valor do quartil de acordo com o ano informado, como também, é através desta coluna que estaremos realizando o particionamento dos dados. Para isso utilizaremos o Bloco de Código 4 a seguir:

— Bloco de Código 4 —

— Criando a Tabela TableIncrementalStatistics —

CREATE TABLE TableIncrementalStatistics
(ID Int Null,
Acao NVarchar(40) Default NewID(),
Data DateTime Null,
Quartil  AS (datepart(year,[Data])*(10)+datepart(quarter,[Data])) PERSISTED
) ON PartitionSchemeIncrementalStatistics (Quartil)
Go

Ótimo, toda estrutura para armazenar nossos dados já esta pronta, bem como, a lógica para distribuir e particionar os dados que serão inseridos na tabela TableIncrementalStatistics.

Ufa, ainda temos um bom caminho pela frente, mas já avançamos bastante, agora temos realizar uma alteração nas configurações do nosso banco de dados IncrementalStatistics, sendo esta necessária para podermos aplicara o uso de estatísticas incrementais, estou me referindo a opção Auto Create Statistics muito conhecida, onde vamos alterar o seu valor default para Incremental = On, conforme apresenta o Bloco de Código 5 abaixo:

— Bloco de Código 5 —

— Habilitando o uso de Incremental Statistics —
Alter Database IncrementalStatistics
Set Auto_Create_Statistics On (INCREMENTAL = On)
Go

O próximo passo consiste na criação do índice que iremos utilizar em na TableIncrementalStatistics pois você deve ter notado que realizamos a criação da tabela sem a definição de uma chave primária, desta maneira  utilizamos o Bloco de Código 6 para criação dos respectivo índice em seguida confirmamos se esta tabela esta fazendo uso das estatísticas incrementais habilitada no bloco de código 5:

— Bloco de Código 6 —

— Criação do índice Clustered —
Create Clustered Index Ind_TableIncrementalStatistics_ID
On [TableIncrementalStatistics] (ID)
GO

— Confirmando se as estatísticas incrementais está habilita —
SELECT
OBJECT_NAME(object_id) TableName
,name
,is_incremental
,stats_id
FROM sys.stats
WHERE name = ‘Ind_TableIncrementalStatistics_ID’
Go

Figura 1 – Confirmando o uso das estatísticas incrementais no índice Ind_TableIncrementalStatistics_ID.

Observação: Note que ao executar o Select realizado na visão de sistema sys.stats a coluna Is_Incremental deverá retornar e apresentar o valor igual á 1, isso indica que TableIncrementalStatistics esta neste momento fazendo uso das estatísticas incrementais.

Muito bem, chegou a hora de popular nossas tabelas, realizaremos a inserção de 8.000 linhas de registros, sendo estes particionados em grupos de 2.000 registros para cada partição que forma e compõem a estrutura da nossa tabela. Vamos então utilizar o Bloco de Código 7 apresentado na sequência:

— Bloco de Código 7 —

— Inserindo os dados na TableIncrementalStatistics —
Insert Into TableIncrementalStatistics (ID, Data)
Values (1, ‘2017-11-22’)
Go 2000

Insert Into TableIncrementalStatistics (ID, Data)
Values (2, ‘2017-06-05’)
Go 2000

Insert Into TableIncrementalStatistics (ID, Data)
Values (3, ‘2017-01-25’)
Go 2000

Insert Into TableIncrementalStatistics (ID, Data)
Values (4, ‘2017-08-13’)
Go 2000

Após a inserção das 8.000 linhas de registros, vamos confirmar a distribuição dos dados através do Bloco de Código 8 declarado abaixo, conforme ilustra o resultado da Figura 2:

— Bloco de Código 8 —

— Consultando a distribuição e particionamento dos dados —
Select partition_number, rows
From sys.partitions
Where OBJECT_NAME(OBJECT_ID)=’TableIncrementalStatistics’
Go

Figura 2 – Distribuição dos dados na tabela TableIncrementalStatistics de acordo com o valor e partição.

Estamos chegando no final, agora vamos realizar algumas manipulações no conjunto de dados armazenados na tabela TableIncrementalStatistics afim de forçarmos o processos de atualização das estatísticas, procedimento que vai nos ajudar a entender o processo de incremento na atualização das estatísticas de armazenamento e processamento utilizados pelo Microsoft SQL quando solicitado acesso aos dados armazenados em nossa table, para tal operação vamos utilizar o Bloco de Código 9:

— Bloco de Código 9 —

— Consultando dados na TableIncrementalStatistics —
Select Id, Acao, Data, Quartil From TableIncrementalStatistics
Where ID = 1
Go

Select Id, Acao, Data, Quartil From TableIncrementalStatistics
Where ID >= 2
Go

Select Id, Acao, Data, Quartil From TableIncrementalStatistics
Where ID <> 3
Go

Pronto, realizamos algumas operações de Select com intuito de forçar a criação de novas estatísticas, e principalmente a atualização das estatísticas atuais. Por enquanto nada de diferente, na sequência vamos consultar as informações sobre as estatísticas relacionadas a nossa tabela, fazendo uso do Bloco de Código 10 e analisando o resultado apresentado através da Figura 3:

— Bloco de Código 10 —

— Consultando as informações sobre as estatísticas da tabela TableIncrementalStatistics —
Select object_id, stats_id , last_updated , rows , rows_sampled , steps
From sys.dm_db_stats_properties(OBJECT_ID(‘[TableIncrementalStatistics]’),1);
Go

Figura 3 – Dados relacionados a estatísticas da TableIncrementalStatistics.

Como você pode ver, o DMF sys.dm_db_stats_properties mostra-nos que as estatísticas foram atualizadas na data do dia 23/05/2017 ás 16:55, para a tabela que tem 8000 linhas.

Neste momento, podemos nos perguntar: Qual partição da tabela inclui as estatísticas atualizadas?

A resposta para esta sua pergunta vem justamente atráves do uso nova DMF sys.dm_db_incremental_stats_properties já apresentada aqui no meu blog. Sendo esta DMF responsável em apresentar as propriedades estatísticas incremental, recuperando as mesma informação obtida a partir do DMF sys.dm_db_stats_properties, também super conhecida e apresentada no meu blog. Neste caso a sys.dm_db_stats_properties vai apresentar dados de  cada partição da tabela particionada, fornecendo-lhe com os mesmos parâmetros; a identificação do objeto e a identificação de estatísticas.

Caminhando mais um pouco, estamos próximos do final, vamos então formar o SQL Server a justamente realizar o processo de atualização das estatísticas para nossa partição de número 3, realizando o processo de exclusão de 1.500 linhas de registros, em seguida consultando nossa TableIncrementalStatistics, conforme apresenta o Bloco de Código 11:

— Bloco de Código 11 —

— Excluíndo 1.500 linhas —
Delete Top (1500) From TableIncrementalStatistics
Where ID = 2
Go

— Consultando os dados —
Select Id, Acao, Data, Quartil From TableIncrementalStatistics
Where ID <> 4
Go

Agora vamos novamente consultar os dados estatísticas, sendo assim repita a execução do Bloco de Código 10, observe que você deverá receber um conjunto de valores similares a Figura 4, onde a coluna Last_Updated deverá apresentar a data e hora da última atualização:

Figura 4 – Data e hora da última atualização da estatística.

Ufa, estamos quase lá, agora chegou a hora da verdade, hora de comprovar se realmente o SQL Server esta fazendo as coisas certas, vamos fazer uso da DMF sys.dm_incremental_stats_properties para validar se a estatística da partição 3 foi atualizada, o resultado pode ser analisado através da Figura 5. Para isso vamos utilizar o Bloco de Código 12 a seguir:

— Bloco de Código 12 —

— Consultando as informações sobre as estatísticas incrementais —
Select object_id, stats_id,
partition_number,
last_updated,
rows, rows_sampled,
steps
From sys.dm_db_incremental_stats_properties(OBJECT_ID(‘TableIncrementalStatistics’),1)
Go

Figura 5 – Informações sobre as atualizações de estatísticas, onde a partição 3 foi atualizada de maneira independente das demais.

Sensacional, conseguimos, muito legal este recurso, como sempre o Microsoft SQL Server nos surpreende com a sua capacidade e potencialidade de recursos.

Referências

Post Anteriores

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

Administrar, gerenciar, cuidar e prover um ambiente sempre no melhor estado possível não é uma das atividades mais tranquilas e simples desempenhadas por profissionais ou administradores de banco de dados, mas também não pode ser considerada um “bicho de sete cabeças” ou uma “caixa preta” ainda mais quando este servidor de banco de dados utiliza o Microsoft SQL Server.

Neste post você pode conhecer um pouco mais de como o Microsoft SQL Server trabalha de maneira árdua na busca da melhor maneira para encontrar e retornar os dados solicitados em nossas transações. Ao longo de novas versões o produto esta cada vez mais maduro, confiável e inteligente, sempre nos surpreendendo com sua capacidade.

Algo que não poderia ser diferente no uso das Estatísticas Incrementais, recurso que nos permite adotar uma nova maneira de atualização dos dados internos relacionados ao armazenamento das nossas informações, mas principalmente prover um auxílio para próprio Database Engine mas atividades para identificar o melhor caminho para se processar uma query.

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 logo logo…

Valeu….

Dica do Mês – Microsoft SQL Server – Identificando as transações que estão utilizando o Transact Log


Bom dia pessoal, tudo bem?

Véspera de feriado religioso e um dos mais importantes para boa parte da população mundial! Justamente por ser véspera de feriado hoje é um daqueles dias que qualquer profissional da área de banco de dados reza para que nada ocorra de errado próximo ás 17hrs ou mais conhecido como 5 horas da tarde.

Pensando neste tipo de necessário o post de hoje dedicado a sessão Dica do Mês tem o objetivo de ajudar você profissional que esta em apuros neste momento tentando identificar o que pode estar ocorrendo em seu ambiente ou servidor Microsoft SQL Server.

Hoje vou apresentar como você pode no Microsoft SQL Server a partir da versão 2008 R2 identificar quais transações estão realizando o acesso e demandando informações para o Transact – Log, arquivo utilizado por qualquer banco de dados existente em seu servidor ou instância SQL Server para registrar dados relacionados as transações atuais ou já processadas, sendo este mais conhecido como log de transações.

Estão vamos em frente…..


Introdução

Quando se referimos ao log de transações, temos sempre aquele boa e velha definição, “o transact log é o arquivo utilizado pelo banco de dados para registrar o que esta sendo processado por nossas transações, conhecido como o dedo duro”, na verdade o transact-log é bem mais do que isso, trata-se de um dos principais componentes de qualquer banco de dados criado no Microsoft SQL Server que nos permite através do seu uso garantir a continuidade e disponibilidade de nossos dados para diversos cenários de armazenamento e principalmente recuperação de informações.

Durante o processamento de uma ou mais querys o transact-log pode apresentar comportamentos diversas de acordo com o que esta sendo processado, mas principalmente no que se relacionado aos processos de escrita e leitura do log, onde nossas querys podem gerar processos de gravação de dados no transact-log e internamente o SQL Server pode necessitar a acessar outros dados em log para atender outras possíveis demandas.

Estes processos são conhecidos como leitura ou escrita do transact-log, situações que podem impactar aleatoriamente no processamento de nossas querys.

Pensando neste tipo de possibilidade, o post de hoje visa ilustrar e apresentar como através do Management Studio ferramenta de administração e gerenciamento do Microsoft SQL Server podemos em conjunto com as DMVs – Dynamic Management Views listadas abaixo, monitorar, catalogar e identificar quais querys ou transações estão fazendo uso do Transact-Log em possíveis processos de leitura ou escrita do log.

Dynamic Management Views

Para saber mais sobre cada DMV acesse as referências apresentadas no final do post:

  • sys.dm_tran_session_transactions;
  • sys.dm_tran_active_transactions;
  • sys.dm_tran_database_transactions;
  • sys.dm_exec_sessions;
  • sys.dm_exec_requests; e
  • sys.dm_exec_sql_text.

O Cenário

Para tentar ilustrar como podemos realizar de maneira fácil este tipo de monitoramento e identificação, vamos criar um pequeno cenário através do Bloco de Código 1, onde estaremos realizando a criação de um novo banco de dados denominado UsingTransactLog para armazenar a tabela TabelaTransactionLog.

— Bloco de Código 1 —
— Criando o banco de dados —
Create Database UsingTransactLog
Go

— Acessando o banco de dados —
Use UsingTransactLog
Go
— Criando a tabela —
Create Table TabelaTransactLog
(TransactionID Int Default Current_Transaction_ID(),
TransactionUser Varchar(100) Default System_User,
TransactionDate DateTime Default Current_TimeStamp)
Go

 

Note que nosso tabela TabelaTransactLog possui um simples estrutura composto por três colunas: TransactionID, TransactionUser e TransactionDate, sendo estes elementos básicos utilizados para catalogar o ID da transação em processamento, o usuário conectado ao banco de dados e data/hora do momento da inserção da linha.

Até aqui nada de tão importante, mas importante para podemos simular o uso do log, nosso próximo passo consiste no processamento do Bloco de Código 2, onde estaremos realizando o processamento de uma transação de inserção de 50.000 mil linhas de registros, sendo a operação de insert uma das mais diversas operações que demando processos de escrita ao transact – log, sendo assim, apresento a seguir o Bloco de Código 2:

— Bloco de Código 2 —
Insert Into TabelaTransactLog Default Values
Go 50000

Observe que não estamos passando nenhum tipo de valores para nossas colunas, na verdade estou forçando o SQL Server a utilizar a criação de valores padrões durante o processamento de cada linha de registro através da instrução Default Values (valores padrões), o que vai obrigar nossa instância e ter que gerar valores durante o tempo de processamento e posteriormente registrar em log.

Muito bem, o processamento desta massa de dados, teremos a necessidade de abrir uma nova query para justamente fazer uso do Bloco de Código 3, sendo este o principalmente elemento do nosso cenário, a query que nos permiti monitorar e identificar as transações que estão em tempo real utilizando o transact-log. Então abra uma nova query e log o Bloco de Código 3 apresentado a seguir:

— Bloco de Código 3 —
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
Go

SELECT tst.session_id As ‘Sessão’,
es.original_login_name As ‘Login’,
DB_NAME(tdt.database_id) AS ‘Database’,
DATEDIFF(SECOND, tat.transaction_begin_time, GETDATE()) AS ‘Tempo decorrido’,
tdt.database_transaction_log_record_count AS ‘Espaço Utilizado’,
CASE tat.transaction_state
WHEN 0 THEN ‘A transação não foi completamente inicializada ainda…’
    WHEN 1 THEN ‘A transação foi inicializada, mas não começou…’
    WHEN 2 THEN ‘A transação esta ativa…’
    WHEN 3 THEN ‘A transação foi encerrada…’
    WHEN 4 THEN ‘Foi iniciado o processo de confirmação sobre o transação distribuída…’
    WHEN 5 THEN ‘A transação está em estado preparação e esperando resolução…’
    WHEN 6 THEN ‘A transação foi confirmada…’
    WHEN 7 THEN ‘A transação esta sendo revertida para o estado anterior…’
    WHEN 8 THEN ‘A transação foi revertida para o estado anterior…’
   ELSE ‘Estado da transação desconhecido’
   END AS ‘Estado da Transação’,
SUBSTRING(TXT.text, ( er.statement_start_offset / 2 ) + 1, ((CASE WHEN er.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), TXT.text)) * 2
ELSE er.statement_end_offset
END – er.statement_start_offset ) / 2 ) + 1) AS ‘Query Atual’,
TXT.text AS ‘Query relacionada’,
es.host_name As ‘Hostname’,
   CASE tat.transaction_type
    WHEN 1 THEN ‘Transação Read/Write’
    WHEN 2 THEN ‘Transação Read-Only’
    WHEN 3 THEN ‘Transação de Sistema’
                WHEN 4 THEN ‘Transação distribuída’
            ELSE ‘Tipo de Transação desconhecido’
            END AS ‘Tipo da Transação’,
tat.transaction_begin_time AS ‘Iniciado em’
FROM sys.dm_tran_session_transactions AS tst INNER JOIN sys.dm_tran_active_transactions AS tat
ON tst.transaction_id = tat.transaction_id
INNER JOIN sys.dm_tran_database_transactions AS tdt
ON tst.transaction_id = tdt.transaction_id
INNER JOIN sys.dm_exec_sessions es
ON tst.session_id = es.session_id
INNER JOIN sys.dm_exec_requests er
ON tst.session_id = er.session_id
CROSS APPLY sys.dm_exec_sql_text(er.sql_handle) TXT
ORDER BY [Tempo decorrido] DESC
Go
Pois bem, você pode estar querendo saber um pouco mais sobre o que exatamente esta acontecendo ao processar o Bloco de Código 3, pode ficar tranquilo que a seguir vou fazer um pequeno overview sobre este bloco de código, começando pelo conjunto de colunas retornadas por ele:
  • Sessão – Apresenta o ID da sessão que esta utilizando o transact-log;
  • Login – Nome da conta de login que esta conectada ao SQL Server;
  • Database – Nome do banco de dados utilizado pela query que esta acessando o transact-log;
  • Tempo decorrido – Representa o tempo de processamento que o query esta demandando para utilizar o transact-log;
  • Log Record Count– Identifica a quantidade de registros de log gerados pela query ou transações em processamento;
  • Estado da transação – Esta coluna apresenta o estado atual da query em processamento, sendo este formado por um conjunto de valores;
  • Query Atual – Apresenta as instruções que estão sendo processadas por cada query;
  • Query Relacionada– Apresenta as instruções processadas por querys que podem estar relacionadas com as atuais querys em processamento;
  • Hostname – Apresenta o nome dos hosts utilizados por cada query em processamento;
  • Tipo de Transação – Identifica se a transação em processamento esta realizando acesso de leitura ou escrita ao log, bem como, se esta query é uma query de sistema ou distribuída; e
  • Iniciado em – Apresenta o horário de início do acesso ao transact-log por parte da query em processamento.

Agora que você já conhece um pouco sobre cada coluna que será retornada após o processamento do Bloco de Código 3, vou abordar o uso da instrução Set Transaction Isolation Level declarada no início do código, que possui a finalidade de alterar no nível de isolamento do nosso banco de dados para Read Uncommitted afim de força o SQL Server a descartar ou desconsiderar qualquer possível ocorrência de bloqueios tanto no nível de tabela e registros, mas principalmente no escopo de banco de dados.

Nota: Se você me perguntar que isso é obrigatório ser feito para conseguir identificar as querys que estão utilizando o transact-log eu vou responder NÃO, isso não é obrigatório, mas pode ser considerada uma possível solução para garantir que o Bloco de Código 3 possa ser processado e consultar as dynamic management views na busca das informações catalogadas por ela em tempo de execução.

Ufa, estamos quase lá, agora nos resta fazer a execução do mesmo e observar o retorno dos dados coletados por este bloco de código, com base, na Figura 1 apresentada abaixo:

Figura 1 – Relação de querys em execução utilizando transact-log.

Perfeito, nosso monitoramento funcionou, conseguimos coletar os dados referentes as querys que estão neste momento em processamento fazendo acesso e utilizando o transact-log criado para o banco de dados UsingTransactLog.

Isso não é sensacional, desta forma, chegamos ao final de mais um post dedicado a sessão Dica do Mês, espero que você tenha gostado.

Referências

Post anteriores

  1. https://pedrogalvaojunior.wordpress.com/2017/03/01/dica-do-mes-microsoft-sql-server-2016-sp1-novo-argumento-use-hint-disponivel-para-query-hints/
  2. https://pedrogalvaojunior.wordpress.com/2017/01/16/dica-do-mes-conhecendo-a-nova-dmf-sys-dm_exec_input_buffer-no-microsoft-sql-server-2016/

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

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

Conclusão

Administrar, gerenciar, cuidar e prover um ambiente sempre no melhor estado possível não é uma das atividades mais tranquilas e simples desempenhadas por profissionais ou administradores de banco de dados, mas também não pode ser considerada um “bicho de sete cabeças” ou uma “caixa preta” ainda mais quando este servidor de banco de dados utiliza o Microsoft SQL Server.

Neste post você pode observar que através do uso de alguns DMVs – Dynamic Management Views a Microsoft nos permite coletar, analisar e entender de forma visual e muito intuitiva como o um servidor ou instância SQL Server gerencia o que esta sendo processado por nossas aplicações, querys ou transações no que se relaciona aos seus componentes e recursos internas, algo que nos permite em diversas situações de administração ou manutenção tentar identificar o que pode estar ocorrendo, bem como, impactando em nosso ambiente.

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, bom feriado, espero que neste momento você não esteja no seu trabalho tentando resolver problemas do seu servidor (kkkkk).

Valeu….

Dica do Mês – Microsoft SQL Server 2016 SP1 – Novo argumento USE HINT disponível para Query Hints


Boa tarde minha comunidade, salve, salve meu mestre SQL e porta bandeira Server……

É isso pessoal, quarta – feira de cinzas para muitos no brasil, mas graças a deus deste mal ou depressão eu não vou morrer, estou retornando em mais um post da sessão Dica do Mês, e se por acaso você não tem acessado o meu blog nos últimos meses não tem problema, uso um dos links abaixo para acessar as três últimos dicas do mês publicadas:

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

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

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

Hoje vou destacar mais uma melhoria adicionada recentemente ao Microsoft SQL Server 2016 a partir da instalação do Service Pack 1, sendo este sem dúvida nenhuma o maior conjunto de melhorias e inovações já adicionadas ao SQL Server desde suas primeiras versões.

Caso você ainda não fez download deste service pack, não perca tempo, acesse o link abaixo e realize o download o quanto antes: https://pedrogalvaojunior.wordpress.com/2016/11/19/microsoft-disponibiliza-service-pack-1-para-o-microsoft-sql-server-2016/

Dando continuidade, hoje vou apresentar o novo Query Hint adicionado após a instalação do SP1 chamado de USE HINT, quando encontrei informações sobre este novo recursos acabei ficando um pouco confuso e sem entender em qual momento ele poderia ser útil, mas após um busca mais detalhada pude ter a certeza que valia a pena compartilhar um pouco sobre esta novidade com vocês.

Se você ainda não ouvir falar sobre uso de query hints ou dicas de consulta existentes no SQL Server, isso assunto não é nada novo muito pelo contrário trata-se de uma das práticas mais comuns utilizadas por profissionais de bancos de dados e desenvolvedores com objetivo de otimizar a execução de uma ou mais transações.

Agora no SP1 do 2016 o time de engenheiros do SQL Server adicionou este novo argumento que nos permite dentre suas finalidades fazer uso de alguns dos mais específicos query hints sem exigir elevação no nível de permissão, declaração de trace flags ou até mesmo que o usuário que esteja fazendo uso deste hint pertença ao server role sysadmin.

Bom se você quiser saber um pouco mais sobre este novo argumento, continue lendo este post….


Introdução

Cenários no qual SQL Server deve ser sugerido mudança de comportamento para o query optimizer são bastante comuns de serem encontrados, tradicionalmente o uso de query hints apresentam um papel fundamental neste contexto independente de qual sinalizador você esteja utilizando, sendo este reconhecido como um documentado ou não-documentados.

Entretanto, quando estes sinalizadores de rastreamento são definidos globalmente, eles podem ter um efeito adverso sobre outras cargas de trabalho. Além disso, o uso por sessão não é prático com aplicativos, bem como, por consulta com QUERYTRACEON, sendo que esta opção requer associação na função de servidor fixa sysadmin. Embora você pode contornar esse comportamento usando um guia de plano ou um procedimento armazenado, credenciais elevadas são ainda necessárias.

Estes sinalizadores de rastreamento são conhecidos como trace flags,  usados para configurar temporariamente características de servidor específico ou para desligar um determinado comportamento, podem ser difíceis de gerenciar e compreender sua forma de uso ou impactos.

A partir do Microsoft SQL Server 2016 SP1 temos a capacidade de fazer uso do novo query hint argument USE HINT diretamente em nossas querys ou transações de forma simples, rápida e segura, contornando qualquer necessidade de elevação permissional ou mudança no contexto de execução.

Dentre os diversos query hints existentes no SQL Server, o USE HINT nos permite fazer uso dos seguintes:

Opção Sinalizador de rastreamento equivalente Descrição
FORCE_LEGACY_CARDINALITY_ESTIMATION TF 9481 Permite que você defina o modelo de estimativa de cardinalidade do otimizador de consulta para o SQL Server 2012 e versões anteriores, independentemente do nível de compatibilidade do banco de dados.
ENABLE_QUERY_OPTIMIZER_HOTFIXES TF 4199 Controles de consulta alterações otimizador lançadas em Service Packs e atualizações cumulativas do SQL Server.
DISABLE_PARAMETER_SNIFFING TF 4136 Desabilita o parâmetro de rastreamento, a menos que o valor OPTION(RECOMPILE), WITH RECOMPILE ou OPTIMIZE FOR seja usado.
ASSUME_MIN_SELECTIVITY_FOR_FILTER_ESTIMATES TF 4137 Faz com que o SQL Server gere um plano usando seletividade mínima ao estimar e predicados para filtros de correlação, em modelo de estimativa de cardinalidade de consulta otimizador do SQL Server 2012 e versões anteriores.
DISABLE_OPTIMIZER_ROWGOAL TF 4138 Faz com que o SQL Server gere um plano que não usa ajustes de meta de linha com consultas que contenham as palavras-chave TOP, OPTION (FAST N), IN ou EXISTS.
ENABLE_HIST_AMENDMENT_FOR_ASC_KEYS TF 4139 Ativar automaticamente gerado estatísticas rápidas (emenda do histograma), independentemente do status da coluna de chave. Se essa opção for usada, independentemente do status de coluna estatísticas principais (em ordem crescente, decrescente ou papel de carta), o histograma usado para estimar a cardinalidade será ajustado em tempo de compilação de consulta.
ASSUME_JOIN_PREDICATE_DEPENDS_ON_FILTERS TF 9476 Faz com que o SQL Server gerar um plano usando a suposição de confinamento simples em vez da suposição de confinamento de Base padrão, no query optimizer cardinalidade estimativa modelo do SQL Server 2014 através de versões do SQL Server 2016.
DISABLE_OPTIMIZED_NESTED_LOOP TF 2340 Faz com que o SQL Server não use uma operação de classificação (classificação em lotes) para associações de loop aninhado otimizado ao gerar um plano.
FORCE_DEFAULT_CARDINALITY_ESTIMATION TF 2312 Permite que você definir o modelo de estimativa de cardinalidade de Otimizador de consulta para o SQL Server de 2014 por meio de versões do SQL Server 2016, dependentes do nível de compatibilidade do banco de dados.

Para consultar esta relação de hint options disponíveis para uso com USE HINT, a Microsoft adicionou um nova DMV denominada: sys.dm_exec_valid_use_hints, sendo esta melhor detalhada no próximo post da sessão Para que serve (não deixe de conferir). A seguir destaco algumas formas de uso do novo USE HINT em conjunto com alguns hints options.

Exemplos

Para ilustrar e ajudar a entender melhor os exemplos a seguir, utilize o banco de Dados AdventureWorksDWCTP3 disponível para download através do link: https://www.microsoft.com/en-us/download/details.aspx?id=49502

— Exemplo 1 – Utilizando o hint option FORCE_LEGACY_CARDINALITY_ESTIMATION —

usehint

— Exemplo 2 – Utilizando o hint option FORCE_LEGACY_CARDINALITY_ESTIMATION em conjunto com a QUERYTRACEON 9481 —

usehint2

Dica: Para que você possa entender e analisar melhor como o SQL Server 2016 se comportar a partir do momento que o argumento USE HINT é declarado, recomendo que você habilite a apresentação do recurso de Include Actual Execution Plan em seu Management Studio e execute estes exemplos sem a declaração do USE HINT e posteriormente com a declaração do mesmo, além disso, também realize a comparação dos planos de execução para notar e identificar as mudanças comportamentais.

Referências

·         https://msdn.microsoft.com/en-us/library/ms188396.aspx

·         https://support.microsoft.com/en-us/help/3189813/update-introduces-use-hint-query-hint-argument-in-sql-server-2016

·         https://msdn.microsoft.com/en-us/library/ms181714.aspx

·         https://msdn.microsoft.com/en-us/library/mt791356.aspx

·         https://blogs.msdn.microsoft.com/sql_server_team/developers-choice-use-hint-query-hints/

Conclusão

Como de costume a cada nova versão ou atualização a Microsft esta apresentando diversas inovações e melhorias no Microsoft SQL Server, mantendo o produto no seu mais alto nível de funcionalidades, recursos e inovações.

Neste post você pode perceber mais uma melhoria adicionada ao produto, onde através deste novo query hint USE HINT temos a capacidade de usar dicas de consulta orientando o query optimizer a mudar sua forma de execução e comportamento sem necessitarmos de elevação no nível de permissão ou fazermos partes de uma função de servidor sysadmin, algo que representa uma grande evolução por parte do produto no que se relacionado a controle de permissões e níveis de segurança.

Sinceramente eu vejo este novo recurso como um pequeno easter egg, pois na minha humilde opinião estava muito mas muito bem escondido.

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.

Valeu….