“T-SQL Querying” – resenha do livro

Quando resolvi conhecer o gerenciador de banco de dados SQL Server, o primeiro livro que li foi “Microsoft SQL Server 2008 – Passo a Passo”, de Mike Hotek. Não me recordo de qual foi o critério que utilizei para adquirir esse livro, mas ele foi a introdução. Pouco mais de 500 páginas, li de cabo a rabo. Acho. Na leitura inicial devo ter assimilado pouca coisa, mas foi a porta de entrada. Então, optei em aprofundar na parte de desenvolvimento: a programação em T-SQL.

Obtive os livros “Inside Microsoft SQL Server 2008 – T-SQL Querying” e “Inside Microsoft SQL Server 2008 – T-SQL Programming”, ambos de Itzik Ben-Gan. Li o primeiro avidamente, testando no computador todos os códigos e realizando variações por contra própria. Terminei o primeiro e passei para o segundo, e gostei mais ainda. Após ler os dois, resolvi relê-los. Não rolou. Ficou enfadonho repetir os mesmos exercícios. Foi quando resolvi participar de fóruns técnicos de SQL Server para agilizar o aprendizado, mas isso é outra história que inclusive foi assunto do artigo “Sete anos de participação em fóruns SQL Server do MSDN & TechNet”.

p044_T-SQL-Querying-2014Terminado o momento nostalgia, vamos ao assunto do dia que é o livro T-SQL Querying, de Itzik Ben-Gan. O exemplar que tenho é da terceira edição, de 2015 e o livro foi escrito tendo o SQL Server 2014 como versão base. São 800 páginas em letra miúda, me parecendo uma reunião do conteúdo dos dois livros dele que citei anteriormente. E não o li de cabo a rabo. Há tópicos nele que provavelmente ainda não li, mas venho utilizando-o como referência em T-SQL e oportunidade de rever/aprender alguns assuntos.

Atenção: Este não é um livro para aprender a linguagem SQL mas sim para utilizar o dialeto T-SQL e o gerenciador SQL Server de forma eficiente.

Folheando o sumário do livro percebo semelhanças com os dois livros dele que mencionei anteriormente mas também observo uma reorganização.

O conteúdo está distribuído em 11 capítulos:

Capítulo Descrição Páginas
1 Logical Query Processing 39
2 Query Tuning 147
3 Multi-Table Queries 71
4 Grouping, Pivoting and Windowing 81
5 TOP and OFFSET-FETCH 31
6 Data Modification 45
7 Working with Date and Time 53
8 T-SQL for BI Practitioners 51
9 Programmable Objects 146
10 In-Memory OLTP 35
11 Graphs and Recursive Queries 96
index 34

Atenção: Este não é um livro para aprender a linguagem SQL mas sim para utilizar o dialeto T-SQL e o gerenciador SQL Server de forma eficiente.O livro contém uma profusão de códigos Transact-SQL, a maioria acessando banco de dados próprio. Tanto o banco de dados quanto os códigos t-sql estão disponíveis para download, permitindo ir testando cada código à medida que se lê o livro.

1. Logical Query Processing

Paro de escrever para folhear o capítulo 1, que explica como é o processamento lógico de uma consulta SQL. Comparo mentalmente com o que aprendi nos últimos anos, em especial a parte de planos de execução; o lógico não é o mesmo que o físico. Entretanto, é bom conhecer bem qual é a sequência do processamento lógico, de modo a não se perder durante a construção de códigos SQL e cometer erros bobos. Na página 5 há um fluxograma da sequência, que gostaria de transcrever a seguir mas não posso pois teria que antes pedir permissão do editor. Até existe uma série de artigos de Itzik Ben-Gan sobre esse assunto, publicados originalmente na SQL Magazine mas que quando foram migrados para o sítio web IT Pro as imagens sumiram. A série inicia em Logical Query Processing: What It Is And What It Means to You e de certa forma é o conteúdo deste primeiro capítulo.

O capítulo contém os seguintes tópicos: Logical query-processing phases; Sample query based on customers/order scenario; Logical query-processing phase details; e Further aspects of logical query processing.

2. Query Tuning

É curioso que logo no segundo capítulo o assunto seja otimização de consultas, antes mesmo de tratar da construção de consultas em t-sql. Este capítulo é extenso; entretanto, a parte inicial (páginas 41 a 97) deste capítulo contém explicação bem didática do funcionamento interno de tabelas e índices bem como das combinações de acesso aos dados. A compreensão desse conteúdo é fundamental para entender o que ocorre durante o processamento da consulta sql.

O capítulo contém os seguintes tópicos: Internals; Tools to measure query performance; Access methods; Cardinality estimates; Index features; Prioritizing queries for tuning with extend events; Index and query information and statistics; Temporary objects; Set-based vs. iterative solutions; Query tuning with query revisions; e Parallel query execution.

3. Multi-table queries

Consultas com várias tabelas remetem o pensamento imediatamente ao operador JOIN. Entretanto, há também as subconsultas (sejam independentes ou correlacionadas), as expressões de tabela (nas formas de CTE, visão, função table-valued ou de tabela derivada) e outras maneiras de utilizar mais de uma tabela em uma mesma consulta e este é o conteúdo deste capítulo.

O capítulo contém os seguintes tópicos: Subqueries; Table expressions; The APPLY operator; Joins; e The UNION, EXCEPT, and INTERSECT operators.

4. Grouping, pivoting, and windowing

Há muitas consultas em que operações são realizadas sobre conjuntos de dados, às vezes retornando um valor como resultado da operação. Nesses casos temos várias das funções de agregações, em que utilizamos o agrupamento prévio dos dados para então efetuar o cálculo; ou então as funções de janela, que operam em conjuntos (window) e subconjuntos (framing) de dados para efetuar o cálculo solicitado. E é sobre estes casos o conteúdo deste capítulo.

O capítulo contém os seguintes tópicos: Window functions; Pivoting; Unpivoting; Custom aggregations; e Grouping sets.

Funções de janela é assunto recorrente no Porto SQL, acessíveis com a tag função de janela; destaque para o artigo Funções de janela. Sobre pivô existe o artigo Alas & Pivôs.

5. TOP and OFFSET-FETCH

Os filtros tradicionais em SQL – ON, WHERE, HAVING, etc. -, utilizam predicados. Por sua vez, TOP e OFFSET-FETCH são filtros que utilizam o conceito em que se indica a ordem e quantas linhas serão retornadas seguindo a ordem definida.

No texto do capítulo é apresentada uma solução interessante para o caso tradicional “retornar a última venda de cada cliente”, bem como outros semelhantes, com o uso de TOP; está no topo da página 344.

O capítulo contém os seguintes tópicos: The TOP and OFFSET-FETCH filters; Using the TOP option with modifications; TOP N per group; e Median. São poucas páginas, pois não há muito o que escrever sobre o assunto.

Quando tomei conhecimento de OFFSET-FETCH imaginei que seria uma ótima solução para os casos de paginação de resultado de consultas sql; entretanto, ao escrever o artigo “Paginação de resultado de consulta SQL” me deparei com resultados inesperados e foram então propostas outras soluções mais eficientes para determinados cenários.

6. Data modification

O capítulo contém os seguintes tópicos: Inserting data; Sequences; Deleting data; Updating data; Merging data; e The OUTPUT clause.

São 45 páginas neste capítulo, pouco para um assunto extenso. Mas na introdução do capítulo é citado que “… it focuses on the more pragmatics and perhaps less trivial aspects of some of the features”.

A respeito dos tópicos tratados neste capítulo, no Porto SQL encontram-se os artigos “Geração de sequências numéricas” e “Apagar conjunto de linhas em tabelas enormes”.

7. Working with date and time

É preciso atenção especial ao manipular datas e horas no SQL Server, por causa da forma como a documentação e o Management Studio apresentam os valores. Há uma enorme confusão entre a forma de entrada e exibição dos dados e como eles são armazenados, internamente.

O capítulo contém os seguintes tópicos: Date and time data types; Date and time functions; Challenges working with date and time; e Querying date and time data.

No Porto SQL há vários artigos sobre tratamento de data & hora, catalogados com a tag data&hora; destaque para o artigo  “Dominando datas & horas no SQL Server”.

8. T-SQL for BI practitioners

Este capítulo inicia por “Huge amount of data already exist in transactional databases worldwide. There is more and more need to analyze this data. Database ans business intelligence developers need to create thousands, if not millions, of reports on a daily basis. Many of these reports include statistical analyses”.

Tradicionalmente os bancos de dados são utilizados para armazenar dados de processamento transacional (OLTP) mas há também aqueles bancos de dados que armazenam informações temporais para análises gerenciais (data warehousing). Entretanto, a linguagem SQL possui poucos recursos para análises estatísticas. Neste capítulo é explicado o básico da análise estatística e também formas de implementar em T-SQL e usando funções em CLR.

O capítulo contém os seguintes tópicos: Data preparation; Frequencies; Descriptive statistics for continuous variables; Linear dependencies; e Moving averages and entropy.

9. Programmable objects

Objetos programáveis são as funções de usuário, os procedimentos (inclusive os de gatilhos) e são assunto deste capítulo, que também trata de comandos SQL dinâmicos, transações, concorrência e tratamento de erros. E são esses objetos em que se deve ter especial atenção ao programar, considerando-se a busca do melhor desempenho possível.

Programar procedimentos de gatilho (triggers), por exemplo, exige um cuidado especial pois a forma como o SQL Server manipula os eventos que acionam gatilhos (trigger) pode se transformar em verdadeira armadilha para quem programa o procedimento de gatilho e desconhece os detalhes específicos do SQL Server, pois enquanto vários gerenciadores de banco de dados acionam o gatilho uma vez para cada linha (for each row), no SQL Server o gatilho é acionado uma vez para cada instrução DML, conforme detalhado no artigo “Armadilhas na programação de trigger”.

As funções de usuário também merecem atenção com relação ao desempenho, principalmente as funções do tipo escalar. Já a respeito dos procedimentos o cuidado é com o parameter sniffing, assunto também tratado no artigo “Introdução ao parameter sniffing”.

O capítulo contém os seguintes tópicos: Dynamic SQL; User-defined functions; Stored procedures; Triggers; SQLCLR programming; Transaction and concurrency; e Error handling.

10. In-Memory OLTP

O recurso In-Memory OLTP foi introduzido na versão 2014 do SQL Server e era então de uso restrito a poucos cenários. Aliás, somente podia ser utilizado na edição Enterprise. Como o livro foi escrito considerando-se a versão 2014, percebe-se que o capítulo não trata do real potencial deste recurso nas versões atuais (2016 em diante) mas serve como introdução ao assunto.

O capítulo contém os seguintes tópicos: In-Memory OLTP overview; Creating memory-optimized tables; Creating indexes in memory-optimized tables; Execution environments; e Surface-area restrictions.

11. Graphs and recursives queries

Grafos (árvores, hierarquias etc.) é um dos assuntos raramente tratados em publicações de SQL Server; o outro assunto refere aos dados espaciais (geográficos). Geralmente a manipulação de grafos se faz em linguagens de programação e utilizando o banco de dados como repositório, mas há recursos em T-SQL que permitem fazer o tratamento diretamente.

O plano de contas de um sistema de contabilidade pode ser considerado exemplo de grafo, mesmo não tendo um único nó raiz mas sim alguns pré-determinados (ativo, passivo, etc.). Desta forma pode-se caminhar pelo plano de contas utilizando algoritmos de grafo. Outro exemplo típico é a lista de materiais (bill of materials, BOM), também denominada de estrutura de produto na indústria, em que relaciona partes que compõem um produto sendo que cada parte pode também ser um produto e utilizado em vários outros produtos. Outra aplicação típica é o organograma.

No capítulo são demonstradas algumas soluções típicas em T-SQL para navegar nos grafos, seja através de CTE recursiva, iteração ou ainda caminho materializado (materialized path).

O capítulo contém os seguintes tópicos: Terminology; Scenarios; Iteration/recursion; Materialized path; Materialized path with the HIERARCHYID data type; Nested sets; e Transitive closure.

Deixe um comentário

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

Logotipo do WordPress.com

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

Foto do Google

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

Imagem do Twitter

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

Foto do Facebook

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

Conectando a %s