Вы находитесь на странице: 1из 335

SQL Server: Alm do Conceito

Blog Post Collection

MVTech |1

SQL Server: Alm do Conceito


Blog Post Collection

MVTech |2

SQL Server: Alm do Conceito


Blog Post Collection

SQL Server: Alm do Conceito


Blog Post Collection

Diego Nogare Edvaldo Castro Demetrio Silva Marcel Inowe Marcos


Freccia Ivan Lima Fabiano Amorim Sulamita Dantas Marcelo
Fernandes Cibelle Castro Leandro Ribeiro Luciano Moreira Nilton
Pinheiro Tiago Balabuch Felipe Ferreira

MVTech |3

SQL Server: Alm do Conceito


Blog Post Collection

MVTech |4

SQL Server: Alm do Conceito


Blog Post Collection

SQL Server: Alm do Conceito


Blog Post Collection
Uma coletnea de posts escolhidos
pelos prprios autores para te
ajudar nas atividades do dia-a-dia.

MVTech |5

SQL Server: Alm do Conceito


Blog Post Collection
Editor: Diego Nogare
Introduo: Edvaldo Castro
Prefcio: Roberto Fonseca
Capa: Felipe Borges
Autores: Diego Nogare Edvaldo Castro Demetrio Silva Marcel
Inowe Marcos Freccia Ivan Lima Fabiano Amorim Sulamita
Dantas Marcelo Fernandes Cibelle Castro Leandro Ribeiro
Luciano Moreira Nilton Pinheiro Tiago Balabuch Felipe Ferreira

MVTech |6

SQL Server: Alm do Conceito


Blog Post Collection

Introduo
Estar envolvido em uma comunidade sempre mais importante e proveitoso
de que viver de um modo isolado, seja nos mbitos pessoais, profissionais e
quaisquer outros. A comunidade tcnica de profissionais que trabalham com
produtos e ferramentas ligados Plataforma de Dados da Microsoft bem
atuante e unida, isso faz com que muito contedo seja gerado, seja com
vdeos, eventos, palestras, entrevistas e postagens em blogs.

Com esta grande quantidade de material correlacionado, um grupo de


amigos que aqui denominados "SQL Friends" teve a ideia de reunir seus
trabalhos em blogs pessoais para criar uma coletnea destes posts e
entregar em uma nica publicao alguns textos de seus blogs.

Os assuntos esto direcionados ao que os autores escrevem geralmente em


seus blogs pessoais, podendo ou no estarem correlacionados entre si. O
mais interessante, que em uma mesma publicao, encontra-se um rico e
variado contedo: Administrao de Banco de Dados, BI, Performance
dentre outros.

SQL Server: Alm do Conceito - Blog Post Collection" foi idealizado para
proporcionar uma experincia variada e com contedo idem, por isso
aprecie o contedo e se tiver alguma dvida ou sugesto, fique vontade
para entrar em contato direto com o autor, atravs do blog do mesmo que
est informado no interior desta publicao.

Um ponto importante a ser mencionado, este trabalho por ser voluntrio e


no ter um cunho com fins financeiros, teve uma tratativa diferente mas no
menos cuidadosa com relao um livro ordinrio. Cada autor o
responsvel direto pelo que escreveu e publicou na coletnea, mas todos
esto juntos para proporcionar e compartilhar o conhecimento que
adquiriram ao longo de vrios anos de experincia.

MVTech |7

SQL Server: Alm do Conceito


Blog Post Collection

Apesar de NO ser um LIVRO formalmente falando, possvel absorver


conhecimento tcnico de alta qualidade escrito pelos autores, exatamente
como pode ser encontrado em seus respectivos blogs.

Aproveite bem, e quaisquer necessidades de contato, no hesite em nos


enviar uma mensagem.
Boa Leitura,
Edvaldo Castro

MVTech |8

SQL Server: Alm do Conceito


Blog Post Collection

Prefcio
A presente obra foi cuidadosamente produzida como fruto de diversos anos
de trabalho e conhecimento dos autores e corresponde a uma compilao
aprimorada de posts publicados por eles no decorrer dos ltimos meses e
extensivamente testado como parte dos seus esforos em adquirir um
conhecimento avanado e aprofundado.

O Microsoft SQL Server 2014 a prxima gerao da Plataforma de


Informao da Microsoft, com novas funcionalidades que entregam um
melhor desempenho, expandem seus dados para a nuvem e provem
estruturas de BI poderosas. O SQL Server 2014 possui dezenas de novas
funcionalidades e melhorias para DBAs, Desenvolvedores e especialistas em
Business Intelligence.

O material aqui apresentado tem como finalidade principal servir como base
de pesquisa para aqueles que tm interesse em entender sobre novas
funcionalidades e evoluir os seus conhecimentos. Neste livro, voc ver
como o SQL Server 2014 utiliza funcionalidades como o Read Committed
Snapshot Isolation, Particionamento de Tabelas, Tuning no Sharepoint e SQL
Server, Importao de Dados com o Integration Services, Auditoria no SQL
Server, Erros de Instalao, Fragmentao do Transaction Log, uso de
Snapshots, Deadlocks, converses e uso de tipos de dados de Datas,
Contadores de Performance e problemas de rede para entregar uma das
melhores ferramentas para a tomada de deciso e gerenciamento de bancos
de dados disponveis no mercado.

Temos a certeza que esta obra ir contribuir consideravelmente para a


desmistificao de muitos tpicos considerados complexos, mostrando no
apenas o significado destes tpicos, mas tambm mostrando o caminho a
seguir para a utilizao no dia-a-dia.

MVTech |9

SQL Server: Alm do Conceito


Blog Post Collection
Desejamos a todos que tirem o melhor proveito deste excelente trabalho e
pedimos que nos informem quaisquer imprecises ou incorrees que
possam ser encontradas nesta obra atravs do email
sqlalemdoconceito@outlook.com, para que possamos sempre manter
disponvel um texto til e eficaz para o seu aprendizado.

Roberto Fonseca

M V T e c h | 10

SQL Server: Alm do Conceito


Blog Post Collection

MVTech
O Minha Vida (http://www.minhavida.com.br) uma empresa com um
grande propsito: melhorar a qualidade de vida da populao. Queremos ser
capazes de despertar nas pessoas o cuidado com a sua prpria sade. E quando
falamos em sade, nos referimos no s preveno ou ao tratamento de
doenas, mas tambm a pequenas mudanas de hbitos capazes de transformar
positivamente o dia a dia das pessoas.

Queremos fazer diferena na vida das pessoas!

Pensando nisso, nosso time de tecnologia criou o MVTech, uma


iniciativa para disseminar conhecimento atravs de iniciativas de seus
colaboradores, buscando o aprimoramento do mercado nacional.

Com diversas aes como: artigos tcnicos em blogs; matrias para


portais; respostas em foruns de discusso, palestras em eventos, eventos
presenciais e online, etc afinal, somos apaixonados pelo que fazemos! por que
no compartilhar nossa paixo?

A criao do MVTech d um passo adiante nesta linha de


compartilhamento de conhecimento, passando a existir um canal oficial onde
podero ser encontrados grandes contedos.

Seja bem vindo ao MVTech


Alexandre Tarifa Diretor de Tecnologia Minha Vida

M V T e c h | 11

SQL Server: Alm do Conceito


Blog Post Collection

M V T e c h | 12

SQL Server: Alm do Conceito


Blog Post Collection

Sumrio
EDVALDO CASTRO ............................................................................... 21
DBA por acidente X Command Line ...................................................................... 21
DBA por acidente ........................................................................................... 21
READ COMMITTED SNAPSHOT ISOLATION Aprecie com moderao ................ 24
RCSI Aprecie com moderao ...................................................................... 24
MUITO BOM...................................................................................................... 24
CENRIO 1 ........................................................................................................... 25
RCSI NO CASO DO SR. JOAQUIM ............................................................................... 25
MAS................................................................................................................ 26
CENRIO 2 ........................................................................................................... 27
O PROBLEMA........................................................................................................ 27
RCSI NESTE CASO .................................................................................................. 27
RESUMINDO:..................................................................................................... 32
PRS E CONTRAS DO RCSI: ...................................................................................... 32
REFERNCIAS .................................................................................................... 33
Artigos tcnicos: O guia definitivo (ou no) .......................................................... 34
MOTIVAO ......................................................................................................... 34
RISCOS E OPORTUNIDADES....................................................................................... 34
QUANDO COMEAR? ............................................................................................. 35
PESQUISE ............................................................................................................. 35
LEIA E ESTUDE MUITO ............................................................................................. 35
FAA CITAES E REFERNCIAS .................................................................................. 36
REVISO PERIDICA (NO OBRIGATRIA) .................................................................... 36
O ARTIGO TCNICO ........................................................................................... 37
TIPOS DE ARTIGOS TCNICOS ............................................................................ 37
DOCUMENTAO................................................................................................... 37
HOW TO(S) .......................................................................................................... 37
BENCHMARKS E EXPERINCIAS .................................................................................. 37
O ARTIGO TCNICO EM SI.................................................................................. 38
ESTRUTURA .......................................................................................................... 38
LINGUAGEM ......................................................................................................... 38
PBLICO ALVO ...................................................................................................... 38
GRAMTICA ...................................................................................................... 39

M V T e c h | 13

SQL Server: Alm do Conceito


Blog Post Collection
EVITE OS ERROS MAIS COMUNS (DIGITAO, GRIAS, CONCORDNCIA, ETC) ......................... 39
SOLICITE REVISES (AMIGOS, COMUNIDADE, PARENTES, SR. JOAQUIM) ............................ 39
PRINCIPAIS PREOCUPAES .............................................................................. 40
SEMPRE ............................................................................................................... 40
NUNCA................................................................................................................ 40
PUBLICIDADE ........................................................................................................ 40
FAA BARULHO ................................................................................................. 41
CONCLUSO ...................................................................................................... 41

DIEGO NOGARE................................................................................... 42
Partition Table ...................................................................................................... 42
Particionamento de Tabelas .............................................................................. 42
CENRIOS/BENEFCIOS ............................................................................................ 44
DEFINIES/TERMINOLOGIAS ................................................................................... 45
CRIANDO FILEGROUP .............................................................................................. 48
CRIANDO PARTITION FUNCTION ................................................................................ 54
CRIANDO O PARTITION SCHEME ................................................................................ 56
CRIANDO A TABELA................................................................................................. 57
COMPARATIVO DE INSERO DE DADOS EM UMA TABELA COM COLUMNSTORE INDEX NO SQL
SERVER 2012 ....................................................................................................... 58

DEMETRIO SILVA ................................................................................. 73


Tuning no SharePoint e SQL Server com o Developer Dashboard ........................ 73
Tunin no SharePoint com Developer Dashboard ............................................... 73
INTRODUO .................................................................................................... 73
CONFIGURAO .................................................................................................... 74
Veja a execuo do script na figura 3: ............................................................... 76
Visualizando o Developer Dashboard ................................................................ 76
CONCLUSO ...................................................................................................... 80
Acessando dados do SharePoint com PowerPivot ................................................ 82
INTRODUO .................................................................................................... 82
REQUISITOS .......................................................................................................... 82
COMO FUNCIONA .................................................................................................. 82
IMPORTAR PARA O POWERPIVOT NO EXCEL ................................................................. 85
CONCLUSO ...................................................................................................... 91
Configurar envio de e-mail no SharePoint / SQL Server com o GMAIL ................. 92

M V T e c h | 14

SQL Server: Alm do Conceito


Blog Post Collection
PASSO 1: CONFIGURAR O SMTP SERVER NO WINDOWS 2008 ........................................ 92

MARCEL INOWE ................................................................................ 101


Dicas sobre o banco de dados do Protheus(Totvs) ............................................. 101
VAMOS AS DICAS: ................................................................................................ 101

MARCOS FRECCIA ............................................................................. 105


Importando arquivos excel usando o SSIS .......................................................... 105
T-SQL no SQL Server 2012 Parte 1 .................................................................... 113
1) EXECUTE WITH RESULT SETS ....................................................................... 113
VAMOS VER COMO FUNCIONA? ............................................................................... 113
2) SEQUENCE .................................................................................................. 115
COMO UTILIZAR? ................................................................................................. 116
PASSO 1: CRIAO DA SEQUENCE. ........................................................................... 116
COMO UTILIZAMOS A SEQUENCE? ............................................................................ 116
RESULTADO. ....................................................................................................... 118
T-SQL no SQL Server 2012 Parte 2 Paginao de dados ................................ 120
CONSULTA 1 ....................................................................................................... 121
CONSULTA 2 ....................................................................................................... 122

IVAN LIMA ......................................................................................... 124


Inside The Machine Introduo ....................................................................... 124
VELOCIDADE DO PROCESSADOR TUDO? ................................................................... 124
REFERNCIAS: ................................................................................................. 128
Inside the Machine Processadores................................................................... 129
INTRODUO .................................................................................................. 129
PROCESSADORES ................................................................................................. 129
OVERVIEW DA MICROARQUITETURA......................................................................... 129
CORE E UNCORE .................................................................................................. 130
PLANTA ............................................................................................................. 130
XEON E7 ........................................................................................................... 131
CORE I5 460M ................................................................................................... 132
MOORES LAW .................................................................................................... 133

M V T e c h | 15

SQL Server: Alm do Conceito


Blog Post Collection
COMPLEXIDADE ................................................................................................... 135
GPGPU ............................................................................................................ 135
CACHE............................................................................................................... 135
REFERNCIAS .................................................................................................. 135
Inside The Machine - Hyper-Threading (SMT) e SQL Server ................................ 137
TEORIA E PRTICA ................................................................................................ 138
MITO ................................................................................................................ 138
PROCESSADORES ................................................................................................. 138
REFERNCIAS: ................................................................................................. 139

FABIANO NEVES AMORIM................................................................. 140


Join reordering e Bushy Plans ............................................................................. 140
INTRODUO .................................................................................................. 140
JOIN REORDERING E BUSHYPLANS ............................................................................ 140
BUSHY PLANS NO SQL SERVER ............................................................................... 141
STATISTICS IO: ................................................................................................. 144
PLANO ESTIMADO: ............................................................................................... 145
STATISTICS IO: ................................................................................................. 149
STATISTICS IO: ................................................................................................. 150
STATISTICS IO: ................................................................................................. 152
STATISTICS IO: ................................................................................................. 153
CONCLUSO .................................................................................................... 154
NOTA IMPORTANTE: ............................................................................................. 154
REFERNCIAS .................................................................................................. 154

SULAMITA DANTAS ........................................................................... 155


Policy Based Management ................................................................................. 155

MARCELO FERNANDES ...................................................................... 162


Solucionando Problemas: Error Failed to open loopback connection ao executar
SP_READERRORLOG ........................................................................................... 162
INTRODUO .................................................................................................. 162
SINTOMA ........................................................................................................... 162
CAUSA .............................................................................................................. 162
SOLUO ........................................................................................................... 163

M V T e c h | 16

SQL Server: Alm do Conceito


Blog Post Collection
LEITURAS ADICIONAIS ............................................................................................ 164
Error to install SQL Server 2008 on Windows 2012............................................. 165
Token Bloat - Cannot generate SSPI context....................................................... 171
PROBLEMA ......................................................................................................... 171
COMO RESOLVER ................................................................................................. 176
EM CADA ESTAO ............................................................................................... 176
LEITURAS ADICIONAIS ..................................................................................... 177

CIBELLE CASTRO ................................................................................ 178


Auditoria ............................................................................................................. 178
Descobrindo Auditoria no SQL Server 2008 ..................................................... 178
POR QUE UTILIZAR AUDITORIA? ............................................................................... 178
PODE SER FEITO ATRAVS DE SCRIPTS........................................................................ 179
NOTA 01: .......................................................................................................... 179
COMO O SQL SERVER AUDIT TRABALHA? .................................................................. 179
NOTA 02: .......................................................................................................... 181
NOTA 03: .......................................................................................................... 184
DATABASE AUDIT SPECIFICATIONS .................................................................. 184
NOTA 03: .......................................................................................................... 186
PASSA A PASSO DE COMO CRIAR UMA AUDITORIA........................................................ 187
FAREMOS ESSAS CONFIGURAES DO SERVER AUDIT ATRAVS DE TSQL E O MANAGEMENT
STUDIO.............................................................................................................. 193
CRIANDO UM SERVER OU SERVER AUDIT SPECIFICATION. .............................................. 200
CRIANDO UM SERVER OU DATABASE AUDIT SPECIFICATION. .......................................... 206
CONCLUSO .................................................................................................... 213
REFERNCIAS .................................................................................................. 213
Performance e Desempenho .............................................................................. 215
System Monitor & SQL Profiler ........................................................................ 215
O QUE O SYSTEM MONITOR? ............................................................................... 215
NOTA 1: ............................................................................................................ 215
NOTA 2 ............................................................................................................. 217
COMO CRIAR UM DATA COLLETOR SETS? .................................................................. 218
PARA CRIAR UM DATA COLLETOR SETS PERSONALIZADO, SIGA OS PASSOS ABAIXO: .............. 218
SQL SERVER PROFILER ..................................................................................... 225
O QUE O TRACE? ............................................................................................... 225
NOTA 4: ............................................................................................................ 228

M V T e c h | 17

SQL Server: Alm do Conceito


Blog Post Collection
COMO APLICAR FILTROS NO SQL PROFILER? .............................................................. 230
PERFORMANCE X MONITORAMENTO ....................................................................... 231
DICA: ................................................................................................................ 231
CRIANDO TRACES ................................................................................................. 231
DICA *: ............................................................................................................. 239
CONCLUSO .................................................................................................... 239
REFERNCIAS .................................................................................................. 239
Restore Database com SSIS ................................................................................ 241
FTP COM WINSCP .............................................................................................. 242
EXECUTE PROCESS TASK ........................................................................................ 244
CRIAO VARIVEIS NO SSIS .................................................................................. 247
FOREACH LOOP CONTAINER ................................................................................... 248
EXECUTE SQL TASK (DELETE DATABASE) .............................................................. 250
EXECUTE SQL TASK (RESTORE DATABASE / USER PERMISSION) ............................ 253
EXECUTE PROCESS TASK (MODIFY NAME FTP FILE) ................................................ 255

LEANDRO RIBEIRO ............................................................................. 256


Fragmentao do Transaction Log - Parte I......................................................... 256
INTRODUO .................................................................................................. 256
TRANSACTION LOG ............................................................................................... 257
Fragmentao do Transaction Log - Parte II........................................................ 260
DICA: ................................................................................................................ 264
VAMOS TESTAR! .................................................................................................. 267
INFORMAO ADICIONAL ....................................................................................... 271
MELHORES PRTICAS: ........................................................................................... 271

LUCIANO MOREIRA ........................................................................... 273


O caso dos snapshots e data cache thrashing ..................................................... 273
DATA CACHE E O DATABASE SNAPSHOT. ......................................................... 273
SCRIPT 1 CRIAO DOS BANCOS DE DADOS .............................................................. 273
SCRIPT 3 RESULTADO DE IO PARA AS CONSULTAS ...................................................... 275
SCRIPT 4 CONSULTANDO O DATA CACHE ................................................................. 275
DATA CACHE THRASHING ................................................................................ 276
SCRIPT 5 CRIANDO DIVERSOS SNAPSHOTS E MAX SERVER MEMORY ................................ 276
SCRIPT 6 UTILIZANDO O ESPAO DO DATA CACHE ...................................................... 277
SCRIPT 7 DATA CACHE THRASHING ........................................................................ 278

M V T e c h | 18

SQL Server: Alm do Conceito


Blog Post Collection
Trigger causando deadlocks................................................................................ 279
PERGUNTA: INDEXAO PODE ELIMINAR PROBLEMAS DE DEADLOCKS? .............................. 279
ENTO PERGUNTO: AONDE EST O DEADLOCK? ........................................................... 280
ENCONTRANDO O DEADLOCK .................................................................................. 280
MINIMIZANDO OS DEADLOCKS ................................................................................ 282
RESOLVENDO O PROBLEMA (DE VERDADE) ................................................................. 284
CONCLUSO .................................................................................................... 285
VARCHAR(MAX) vs. TEXT (Sintaxe?) ................................................................... 287
SCRIPT 01 DUAS TABELAS IDNTICAS, VARCHAR(MAX) E TEXT ................................ 287
SCRIPT 02 ANALISANDO AS UNIDADES DE ALOCAO ................................................. 289
SCRIPT 03 SP_TABLEOPTION PARA LARGE VALUES ..................................................... 289

NILTON PINHEIRO ............................................................................. 293


Trabalhando com datas e converses no SQL Server ......................................... 293
OS TIPOS DE DADOS DATETIME E SMALLDATETIME ..................................................... 293
ENTENDENDO O ARMAZENAMENTO DOS VALORES DATA E HORA...................................... 294
TRABALHANDO COM A PARTE DATA .......................................................................... 296
LISTAGEM 1. SCRIPT PARA CRIAO E POPULAO DA TABELA DE PEDIDOS ........................ 297
FUNES E CONVERSES ....................................................................................... 299
TRABALHANDO COM A PARTE HORA ......................................................................... 302
CONCLUSO .................................................................................................... 305
Monitorando alteraes de Dados com a Clusula OUTPUT .............................. 306
DICAS PARA A UTILIZAO DO OUTPUT ................................................................... 311

TIAGO BALABUCH ............................................................................. 313


PERFORMANCE COUNTER - SUBSISTEMA DE DISCOS ......................................... 313
UTILIZAO DE DISCO ........................................................................................... 313
OS CONTADORES UTILIZADOS PARA MEDIR AS INFORMAES SO: ................................... 313
TEMPO DE RESPOSTA ............................................................................................ 314
REFERNCIAS: ................................................................................................. 315
PROBLEMAS DE REDE ASYNC_NETWORK_IO ................................................... 316
OBJETIVO ........................................................................................................... 316
ANLISE INICIAL BANCO DE DADOS: ...................................................................... 316
ANLISE INICIAL WEB: ....................................................................................... 317
ANLISE DETALHADA ............................................................................................ 318

M V T e c h | 19

SQL Server: Alm do Conceito


Blog Post Collection
OS CONTADORES UTILIZADOS FORAM:....................................................................... 318
AMBIENTE DE BANCO DE DADOS .................................................................... 319
AMBIENTE WEB............................................................................................... 322
RESOLUO ........................................................................................................ 323
CONCLUSO .................................................................................................... 323
REFERNCIAS: ................................................................................................. 324
Suspect database - MSDTC in-doubt transaction ................................................ 325
PROBLEMA ...................................................................................................... 325
RESOLUO .................................................................................................... 326
CONCLUSO .................................................................................................... 327
REFERNCIAS: ..................................................................................................... 328

FELIPE FERREIRA ............................................................................... 329


A carreira de DBA est morrendo? ..................................................................... 329
NO MERCADO DE HOJE NS TEMOS DOIS PROBLEMAS MUITO COMUNS: ............................ 329
Criando um datawarehouse para testes ............................................................. 331
PASSO 1: ........................................................................................................... 331
PASSO 2: ........................................................................................................... 332
PASSO 3: ........................................................................................................... 333
PASSO 4: ........................................................................................................... 334

M V T e c h | 20

SQL Server: Alm do Conceito


Blog Post Collection

Edvaldo Castro
www.edvaldocastro.com

DBA por acidente X Command Line


DBA por acidente

Comeo o texto de hoje falando um pouco deste que um termo muito


comum em rodas de conversas de DBAs e profissionais que se dedicam a
fazer bem feito e com excelncia aquilo que se prope a fazer, neste caso
mais especificamente falando, ser um DBA cada vez melhor Abro aqui um
parntese para indicao de leitura How to become an exceptional DBA.
O DBA por acidente, as vezes nem mesmo sabe que um DBA, a ele so
atribudas atividades de um DBA em paralelo s suas obrigaes e quando
menos se d conta, j est atuando nica e exclusivamente com a
Administrao do SGBD (Aqui, leia-se SQL Server).
Pelo fato de o SQL Server, diferente da maioria dos demais SGBDs, ter uma
interface amigvel e bastante intuitiva, muitos dos DBAs do tipo supracitado,
ao executarem tarefas cotidianas e relativamente simples do dia-a-dia (tais
como: backup, restore, criao de base nova, etc), simplesmente se
acomodam e deixam de buscar conhecimento e entendimento a fundo do
funcionamento da ferramenta, de possveis problemas e solues para
poder atuar de forma mais rpida e efetiva.
Em outros SGBDs, como por exemplo: Oracle e DB2, a administrao da
ferramenta geralmente de certa forma mais complexa e requer maior
conhecimentos das particularidades destas, e talvez por este motivo, seja
muito mais comum a existncia de DBAs por acidente no mundo SQL
Server.
Ainda que o Microsoft SQL Server oferea uma interface super amigvel e
fcil de trabalhar, uma boa forma de se livrar das armadilhas do vcio na
interface grfica que facilita muito a vida do DBA, comear a olhar como
as coisas funcionam em background. Por exemplo, ao executar um backup
simples de uma base de dados via SSMS (SQL Server Management Studio),

M V T e c h | 21

SQL Server: Alm do Conceito


Blog Post Collection
porque no gerar um script da execuo deste backup e das prximas vezes
que se for executar um backup simples, faz-lo via T-SQL apenas alterando o
script previamente gerado? Com o tempo, naturalmente este comando de
backup ser memorizado e no haver mais a necessidade da dependncia
da interface para execuo desta atividade
Um dos pontos, o conhecimento dos cdigos gerados por tras de cada
instruo submetida via interface grfica, mas o estudo e conhecimento
daquilo que se faz (neste caso, Administrar Banco de Dados (SQL Server)), vai
muito alm disto. Neste post, estou dando nfase utilizao de cdigos nas
atividades do dia-a-dia de um DBA, pois acredito ser este um grande passo
para se deixar o rtulo de DBA por acidente para se tornar um profissional
cada vez melhor e saber exatamente aquilo que se est fazendo
Posso citar inmeras vantagens, na utilizao de cdigos de comando ao
invs de interfaces grficas, mas em minha opinio, destacam-se os
seguintes fatores:
Produtividade: Particularmente depois que se adquire prtica, muito mais
rpido criar um usurio, executar um backup ou restore via T-SQL do que
efetuar diversos cliques na tela, para realizar estas tarefas.
Escalabilidade: Para fazer uma operao de backup/restore, pode ser
pequena a diferena de tempo gasto usando tanto interface quanto T-SQL,
porm tente fazer uma operao destas com dezenas ou at mesmo
centenas de bases (e acredite, existem muitos cenrios para isto).
Flexibilidade: Se voc um DBA que usa nica e exclusivamente a interface
grfica do SSMS e mal sabe como as coisas acontecem nos cdigos
executados por suas telinhas, bem possvel que suas mos ficaro
literalmente atadas caso voc se depare com um servidor onde o SQL Server
esteja devidamente instalado, mas no haja o SSMS. Caso voc no seja
totalmente dependente da ferramenta grfica, voc poder (em casos
extremos) trabalhar normalmente conectando-se via SQLCMD.
Alm dos trs fatores supracitados, existem outros diversos, porm no a
inteno ficar enumerando o que considero melhor ou pior em cada um dos
meios de administrao do SQL Server.

M V T e c h | 22

SQL Server: Alm do Conceito


Blog Post Collection
Na minha viso a relao existente entre um DBA por acidente e Linhas de
cdigo, que normalmente DBAs por acidente no se preocupam em
entender como a coisa funciona, e por isto, geralmente continuam a sempre
fazer a mesma tarefa, da mesma maneira, enquanto aqueles que se prope
a ser excelentes profissionais, sempre esto correndo atras de entendimento
e fugindo das limitaes impostas (neste caso, falando sobre utilizar nica e
exclusivamente, Interface Grfica).
Sinceramente, no tenho nada contra quem utiliza interface grfica, desde
que o faa por preferncia, e no por limitao de no saber fazer de outra
maneira. fato que ningum nasce sabendo, ou com Master degree em
nada, mas nunca tarde para comear a correr atras do prejuzo
A inteno do texto realmente no foi em ser tcnico, apenas externar algo
que penso com relao ao assunto que se faz presente nos meios
profissionais

Grande abrao,

Edvaldo Castro
http://edvaldocastro.com

M V T e c h | 23

SQL Server: Alm do Conceito


Blog Post Collection

READ COMMITTED SNAPSHOT ISOLATION Aprecie


com moderao
RCSI Aprecie com moderao

No existe almoo grtis


Muito cuidado com as armadilhas do RCSI

O incio proposital deste post para demonstrar alguns dos benefcios e


tambm os pontos de ateno com a possibilidade da alterao do
comportamento padro de uma base de dados no SQL Server, quando se
trata de concorrncia e isolamento das transaes.
Por padro, o SQL Server tem um comportamento Pessimista, onde o nvel
de isolamento padro o Read Committed, o que basicamente faz com
que o SQL Server tenha um nmero maior de locks, reduzindo a concorrncia
entre as transaes.
Acesse (https://msdn.microsoft.com/enus/library/ms189122(v=sql.105).aspx) para um overview nos Nveis de
Isolamento no SQL Server.

MUITO BOM
Resumidamente, o Read Committed Snapshot Isolation (RCSI), trabalha com
o versionamento de registros, utilizando-se da tempdb para tal, fazendo com
que o comportamento Pessimista do nvel de isolamento Read
Committed onde Leitores (Select) bloqueiam Escritores (Insert, Update e
Delete), e vice-versa, seja substitudo por padro na base em que foi ativado
o RCSI para o comportamento Otimista, onde Leitores (Select) e Escritores
(Insert, Update, Delete) no se bloqueiam.

M V T e c h | 24

SQL Server: Alm do Conceito


Blog Post Collection
Quando h concorrncia entre um Updates e Selects submetidos a um
mesmo registro, gerado uma verso comitada do registro, que ento esta
lida da pela transao que entrou em segundo lugar.
Esta alterao do corportamento Pessimista para Otimista, pela habilitao
do RCSI no acaba com bloqueios entre escritores (update x update) e
tambm no evita bloqueios onde h verificao de constraints (foreign
Keys, por exemplo).
Quando leva-se em considerao o Read Committed Snapshot Isolation Level
apenas at os pontos aqui exibidos, no h mais o que se pensar, pode se ter
a falsa ideia de soluo para todos os problemas de concorrncia e bloqueios
e a ideia de ativ-lo imediatamente em todas as bases SQL Server da
instncia demasiadamente tentadora.
Para Exemplificar melhor, segue uma citao de quando o problema
solucionado habilitando-se o RCSI.

C ENRIO 1
Na padaria do Sr. Joaquim, so produzidos 1.000.000 de pes por dia, e o
sistema de panificao automaticamente faz um update na tabela de pes
produzidos naquele dia. Esporadicamente o Sr. Joaquim gosta de tirar
relatrios para saber a quantidade produzida at ento, porm, seus
relatrios ficam bloqueados por muito tempo, visto que os updates so
constantes e demorados.

RCSI NO CASO DO S R . J OAQUIM


Neste caso especfico, a habilitao do RCSI pode minimizar drasticamente
os problemas do Sr. Joaquim com a lentido de seus relatrios, uma vez que
seus selects no mais esperaro pelos updates automticos realizados
pelo moderno sistema de fabricao de pes.
Os updates continuam sendo realizados com a mesma frequncia, e apenas
bloqueando-se entre si quando necessrios (lembrando que o RCSI no evita
bloqueios entre updates), e quando o Sr. Joaquim submeter um select

M V T e c h | 25

SQL Server: Alm do Conceito


Blog Post Collection
envolvendo os registros bloqueados, ele receber o resultados dos ltimos
comitados e no sero considerados aqueles com transaes em aberto.

MAS

Porm, como mencionado no incio deste post

No existe almoo grtis


Muito cuidado com as armadilhas do RCSI

Adiciono mais uma

Coisas estranhas podem acontecer

No so raras as vezes em que os bloqueios e esperas so benficos e


necessrios, para se evitar erros de negcios ou at mesmo inconsistncias
no valor dos dados de sua base.
O Read Committed Snapshot Isolation, uma excelente opo, fantstica e
que passvel sim, de ser habilitada na maioria das bases de dados da
maioria dos ambientes com SQL Server, porm necessrio um
levantamento cauteloso dos pontos onde podem incorrer problemas pela
habilitao deste comportamento de uma base de dados do SQL Server.
Um dos maiores pontos de ateno que o RCSI habilitado para a base
inteira, fazendo com que o nvel de isolamento das transaes para esta
base, seja por padro alterado. Para que se tenha nveis de isolamento
diferentes, necessrio que estes sejam informados dentro das transaes
submetidas.

M V T e c h | 26

SQL Server: Alm do Conceito


Blog Post Collection
Vale ressaltar que apesar dos cuidados, custos e advertncias supracitados,
normalmente a relao CUSTO X BENEFCIO vale a pena e os problemas em
potencial so poucos, em relao aos benefcios com o uso do RCSI.
Para facilitar um pouco o entendimento, segue uma descrio de um caso
onde o RCSI pode causar um grande problema.

C ENRIO 2
Uma empresa tem um programa conjunto entre as reas Financeira e RH, de
emprstimo de dinheiro da prpria empresa a seus empregados, com
desconto em folha de pagamento. As regras para que o colaborador possa
pegar dinheiro, so bem simplistas e a principal delas, que o e mesmo
esteja empregado.

O P ROBLEMA
Joo Castro, trabalhou por 10 anos na empresa referida, e um belo dia foi
chamado pelo RH que lhe agradeceu pelos servios e o demitiu. Sabendo
Joo que a empresa tinha o programa de emprstimos e que o Depto
Financeiro era logo na sala ao lado, passou diretamente no financeiro e
pegou 20 mil reais que foi prontamente liberado. Joo acabava de ser
demitido e receber 20 mil reais em emprstimo, que no pagaria nunca, visto
que no teria mais vnculo com a empresa.

RCSI NESTE CASO


Supondo que existam 2 Tabelas envolvidas no processo:
TB_PESSOA
TB_EMPRESTIMO
O processo de emprstimo verifica se a pessoa est empregada ou no
(TB_PESSOA) para liberar o dinheiro (TB_EMPRESTO).
Hipoteticamente falando, Joo por demitido por algum do RH que abriu o
sistema para atualizar o status para DEMITIDO, mas antes de executar

M V T e c h | 27

SQL Server: Alm do Conceito


Blog Post Collection
o commit da transao, resolveu ir tomar um caf e a deixou aberta. Joo foi
ao Depto Financeiro, algum deste departamento abriu uma transao para
liberar emprstimo, foi consultar na tabela TB_PESSOA se Joo estava
empregado e recebeu como resultado EMPREGADO, visto que uma
transao de update j estava aberta, porm no havia sido comitada.
Quando o algum do RH voltou, salvou via sistema a demisso de Joo,
alterando seu status para DEMITIDO, porm o campo
SITUACAO_EMPRESTIMO na tabela TB_EMPRESTIMO estava como
LIBERADO.
Neste caso especfico, o bloqueio deveria acontecer e a transao de
liberao do emprstimo obrigatoriamente deveria ser bloqueada pela
alterao na tabela que informa se a pessoa est empregada ou no.
Ainda assim, este no seria um empecilho para a habilitao do RCSI na base,
visto que possvel forar com um HINT que a espera acontea.
Foram criados Scripts para demonstrao do caso citado que podem ser
baixados pelo endereo: http://edvaldocastro.com/rcsi-2/
Ou visualizados no trecho de cdigo abaixo.

CRIAO DO AMBIENTE PARA OS TESTES


CRIAO DA BASE
USE master
GO
IF db_id(DEMO_RCSI) IS NOT NULL
DROP DATABASE DEMO_RCSI
GO
CREATE DATABASE DEMO_RCSI
ON PRIMARY
(NAME = DEMO_RCSI_Data,FILENAME = C:TEMPDE
MO_RCSI.mdf,SIZE = 128 MB)
LOG ON
(NAME = DEMO_RCSI_Log, FILENAME = C:TEMPDE
MO_RCSI.ldf,SIZE = 128 MB)
GO
USE DEMO_RCSI
GO
CRIA A TABELA PESSOA
IF object_id(TB_PESSOA) IS NOT NULL

M V T e c h | 28

SQL Server: Alm do Conceito


Blog Post Collection
DROP TABLE TB_PESSOA
GO
CREATE TABLE TB_PESSOA
(
ID_PESSOA INT IDENTITY CONSTRAINT PK_TB_PESSO
A_ID_PESSOA PRIMARY KEY
,DATA_CONTRATACAO DATE DEFAULT GETDATE()
,NOME_PESSOA VARCHAR(60)
,BOL_EMPREGADO CHAR(1)
)
GO
CRIA A TABELA EMPRESTIMO
IF object_id(TB_EMPRESTIMO) IS NOT NULL
DROP TABLE TB_EMPRESTIMO
GO
CREATE TABLE TB_EMPRESTIMO
(
ID_EMPRESTIMO INT IDENTITY CONSTRAINT PK_TB_E
MPRESTIMO_ID_EMPRESTIMO PRIMARY KEY
,ID_PESSOA INT CONSTRAINT
FK_TB_PESSOA_TB_EMPRESTIMO FOREIGN KEY
REFERENCES TB_PESSOA (ID_PESSOA)
,VALOR_EMPRESTIMO DECIMAL(10,2)
,LIBERACAO_EMPRESTIMO CHAR(1)
)
EXISTE O NVEL DE ISOLAMENTO
EXIBE INFORMAO SOBRE O NIVEL DE ISOLAMENTO
ATUAL
SELECT
NAME
,CASE is_read_committed_snapshot_on
WHEN 1 THEN ENABLED
WHEN 0 THEN DISABLED
END
AS Read_Committed_Snapshot
FROM SYS.DATABASES
WHERE NAME = DEMO_RCSI
CARREGA DADOS NA TABELA PESSOA
INSERT INTO TB_PESSOA (NOME_PESSOA, BOL_EMPRE
GADO)
VALUES (JOAO CASTRO,S)
,(MANOEL MAIA,S)
,(BENEDITO LIMA,N)
,(MARIA CASTRO,N)
,(CLEONTINA OLIVEIRA,S)

M V T e c h | 29

SQL Server: Alm do Conceito


Blog Post Collection
,(CANDIDO DUARTE,S)
ALTERA O NVEL DE ISOLAMENTO PARA RCSI
USE master
ALTER DATABASE DEMO_RCSI SET READ_COMMITTED_S
NAPSHOT ON
EXIBE DADOS DA TABELA PESSOA
SELECT * FROM TB_PESSOA

ID_PESSOA
DATA_CONTRATACAO
NOME_PESSOA
BOL_EMPREGADO
1
2013-07-27
JOAO
CASTRO
S
2
2013-07-27
MANOEL
MAIA
S
3
2013-07-27
BENEDITO
LIMA
N
4
2013-07-27
MARIA
CASTRO
N
5
2013-07-27
CLEONTINA
OLIVEIRA
S
6
2013-07-27
CANDIDO
DUARTE
S
ALTERA NVEL DE ISOLAMENTO
ALTER DATABASE DEMO_RCSI SET
READ_COMMITTED_SNAPSHOT ON
ALTER DATABASE DEMO_RCSI SET
READ_COMMITTED_SNAPSHOT OFF
/**/
TRANSAO T1
TRANSAO DE DEMISSO (T1)
EXIBE INFORMAO SOBRE O NIVEL DE ISOLAMENTO
ATUAL
SELECT
NAME
,CASE is_read_committed_snapshot_on
WHEN 1 THEN ENABLED
WHEN 0 THEN DISABLED
END AS Read_Committed_Snapshot
FROM
SYS.DATABASES
WHERE NAME = DEMO_RCSI
PARA ALTERAR PARA O RCSI
USE MASTER
ALTER DATABASE DEMO_RCSI SET

M V T e c h | 30

SQL Server: Alm do Conceito


Blog Post Collection
READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK
IMMEDIATE
INICIO DA TRANSAO DE UPDATE
BEGIN TRAN T1
SELECT * FROM TB_PESSOA
WHERE NOME_PESSOA = JOAO CASTRO
USE DEMO_RCSI
GO
UPDATE P
SET P.BOL_EMPREGADO = N
FROM TB_PESSOA P
WHERE NOME_PESSOA = JOAO CASTRO
GO
SELECT * FROM TB_PESSOA
WHERE NOME_PESSOA = JOAO CASTRO
ROLLBACK TRAN T1
COMMIT TRAN T1
ABRA A SEGUNDA TRANSAO EM UMA NOVA JANELA
(NEW QUERY)E FAA A OPERAO DE EMPRESTIMO
(T2)
/**/
TRANSAO T2
TRANSAO DE EMPRSTIMO (T2)
- GARANTIR QUE ESTEJA COM RCSI HABILITADO
USE MASTER
ALTER DATABASE DEMO_RCSI SET
READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK
IMMEDIATE
GO

INICIO DA TRANSAO DE UPDATE


BEGIN TRAN T2
USE DEMO_RCSI
GO
INSERT INTO TB_EMPRESTIMO
SELECT ID_PESSOA, 20000,S
FROM TB_PESSOA P
WHERE NOME_PESSOA = JOAO CASTRO
COMMIT TRAN T2

SELECT * FROM TB_EMPRESTIMO


SELECT * FROM TB_PESSOA

M V T e c h | 31

SQL Server: Alm do Conceito


Blog Post Collection
VEJA O RESULTADO ANTES DO COMMIT DA T1
(TRANSAO DE DEMISSO)
SELECT P.ID_PESSOA, P.NOME_PESSOA, E.VALOR_EM
PRESTIMO, P.BOL_EMPREGADO,E.LIBERACAO_EMPREST
IMO
FROM TB_EMPRESTIMO E
JOIN TB_PESSOA P
ON E.ID_PESSOA = P.ID_PESSOA

EXECUTE O COMMIT DA TRANSAO T1 E RODE


NOVAMENTE O RESULTADO. OBSERVER QUE H ERRO
DE NEGCIO
POIS FOI LIBERADO EMPRSTIMOI PARA UMA
PESSOA QUE NO EST EMPREGADA.
SELECT P.ID_PESSOA, P.NOME_PESSOA, E.VALOR_EM
PRESTIMO, P.BOL_EMPREGADO,E.LIBERACAO_EMPREST
IMO
FROM TB_EMPRESTIMO E
JOIN TB_PESSOA P
ON E.ID_PESSOA = P.ID_PESSOA

RESUMINDO:

P RS E C ONTRAS DO RCSI:
Reduz consideravelmente problemas provenientes de bloqueios.
Habilitao fcil e rpida.
Contras do Read Committed Snapshot Isolation:

M V T e c h | 32

SQL Server: Alm do Conceito


Blog Post Collection
No til em bloqueios entre transaes de update.
Bloqueios com verificao de constraints tambm no so beneficiados.
Pode resultar com algum erro negocial no esperado, caso no seja bem
mapeado.

CONCLUSO:

O RCSI passvel de utilizao em qualquer ambiente, desde que os porns


sejam bem mapeados e os erros provenientes sejam mitigados, com o uso
de HINTS (Ex: (SELECT * FROM TABELA WITH (READCOMMITTED)), Alterando
o nvel de isolamento nas transaes que necessitam que os bloqueios
aconteam entre outros meios que podem ser utilizados.

READ COMMITTED SNAPSHOT ISOLATION APRECIE COM MODERAO

REFERNCIAS

http://msdn.microsoft.com/pt-br/library/ms173763.aspx
http://msdn.microsoft.com/en-us/library/tcbchxcb(v=VS.80).aspx

Grande abrao,

Edvaldo Castro
http://edvaldocastro.com

M V T e c h | 33

SQL Server: Alm do Conceito


Blog Post Collection

Artigos tcnicos: O guia definitivo (ou no)


Estar presente e participar ativamente de uma comunidade, sempre ajuda
no crescimento das pessoas, seja ele profissional, pessoal, religioso ou
quaisquer outros mbitos. Para quem trabalha na rea de TI
particularmente, esta participao pode culminar em uma curva de
aprendizado e crescimento profissional muito mais acentuada do que se o
profissional se isolar e caminhar sozinho na carreira.
Basicamente possvel participar de comunidades consumindo informaes
compartilhadas e compartilhando informaes e conhecimentos. Algumas
das principais formas de compartilhar conhecimento e informaes so:
Palestras (presenciais e online), Redes Socais em geral, vdeos, Wiki e Blogs
com postagens tcnicas.
Para aqueles que se aventuraram, ou desejam se aventurar com a redao e
compartilhamento de textos tcnicos, a seguir existe uma serie de pontos
importantes que devem ser observados na inteno de que erros sejam
evitados e uma melhor qualidade seja alcanada.

M OTIVAO
Existem diversos motivos que podem e levam profissionais iniciarem uma
efetiva participao em comunidades tcnicas e criarem seus prprios blogs
pessoais, ou mesmo escreverem para canais j bem conhecidos. Com
motivaes diferentes, geralmente os objetivos so comuns: exposio
profissional, compartilhamento de conhecimento, networking e
reconhecimento. Abaixo, alguns pontos que so relevantes e que podem
influenciar direta ou indiretamente os resultados desta deciso de tornar-se
pblico atravs principalmente de artigos tcnicos.

R ISCOS E O PORTUNIDADES
A Exposio Profissional proveniente da deciso de escrever artigos
tcnicos ambgua, ou seja, pode ser uma excelente oportunidade de se

M V T e c h | 34

SQL Server: Alm do Conceito


Blog Post Collection
criar um timo crculo de contatos profissionais, networking de alto nvel e
gerar grandes benefcios nos mbitos profissional e pessoal, porm esta
mesma Exposio Profissional pode ser extremamente perigosa e
prejudicial carreira do profissional, caso este no tome alguns cuidados
bsicos na hora de expor-se atravs de seus textos, por exemplo: Textos no
fidedignos, com erros de portugus, dentre outros graves erros que esto
melhor detalhados adiante, neste artigo.

Q UANDO C OMEAR ?
Tendo-se conhecimentos dos riscos e oportunidades, e considerando-se
apto a dar incio ao trabalho de compartilhamento de informaes via textos
tcnicos (ou no), existem alguns importantes pr-requisitos a serem
seguidos, para aumentar a probabilidade de que o texto a ser publicado seja
bem recebido e faa sucesso.

P ESQUISE
H um grande equvoco por parte de muitos autores de blogs, que o
conhecimento relacionado a um determinado assunto. Muitas pessoas,
quando prope-se a escrever um artigo tcnico, enganam-se e pensam j
saber o suficiente para no ser necessrio fazer nenhuma pesquisa adicional.
Mero engano, todo e qualquer contedo tcnico, fica muito melhor
apresentado, se expor pontos de vistas diferentes, ou mesmo contedo de
fontes variadas, para defender um ponto de vista, ou mesmo descrever algo.

L EIA E ESTUDE MUITO


Leitura e estudo, nunca demais. E quanto mais conhecimento sobre o
assunto a ser dissertado, melhor e mais rico ficar o artigo tcnico. sempre
muito importante estudar, ler e fazer tantos testes quantos possveis antes
de publicar o artigo, visto que uma vez publicado, seu texto estar exposto
para o mundo inteiro a qualquer momento para visualizao de qualquer
pessoa que quiser visualiz-lo, e conforme j citado anteriormente, pode ser
muito bom ou muito ruim esta exposio.

M V T e c h | 35

SQL Server: Alm do Conceito


Blog Post Collection
F AA CITAES E REFER NCIAS
Um ponto no menos importante que os anteriores a existncia de citaes
e referncias no artigo tcnico dos textos que foram escritos por outros
autores. frustrante para um autor, ver que todo trabalho de pesquisa e
estudo que ele teve para escrever determinado trecho de artigo, ou mesmo
um artigo completo, e repentinamente ver este roubado e publicado sem
referncia em outro local, que at ento era desconhecido. at mesmo
uma questo de respeito e demonstrao de maturidade e bom senso, que
ficaro explcitos aos leitores do artigo em questo.

R EVISO P ERIDICA (N O OBRIGATRIA )


Esta no uma necessidade extremamente importante, mas
esporadicamente interessante ler alguns de seus posts / artigos tcnicos
para que se por algum acaso houver algum erro (digitao, portugus ou
conceitual), este possa ser corrigido.
Revise sua estratgia / metodologia
Um Blog baseado no dia a dia, ou na carreira de um profissional, deve
acompanhar as mudanas que naturalmente ocorrem na carreira. Um bom
exemplo a tendncia de migrao de vrios servios de tecnologia para a
nuvem. Se voc fala sobre infraestrutura de servidores (Windows ou Linux),
por exemplo, considere comear a estudar sobre computao na nuvem, e
medida que sentir-se confortvel, os artigos naturalmente devem
acompanhar esta mudana, isto far com que os leitores, acompanhem as
mudanas e talvez at se consiga mais leitores assduos dos artigos tcnicos
publicados.

M V T e c h | 36

SQL Server: Alm do Conceito


Blog Post Collection
O ARTIGO TCNICO
Abaixo, listo algumas caractersticas e especificidades referentes aos tipos
mais comuns de artigos tcnicos, detalhes do mesmo e alguns pontos de
observao no que se refere gramtica na redao destes.

TIPOS DE ARTIGOS TCNICOS

D OCUMENTAO
Este tipo de artigo tcnico visa dissertar sobre algum produto, feature ou
atividade, demonstrando sua finalidade sem se preocupar na apresentao
dos mtodos ou passo a passo para implementao. Este tipo de artigo
tcnico, geralmente escrito quando so lanadas verses novas ou um
produto totalmente novo, com a finalidade principal de demonstrar tal
produto ou feature.

H OW T O ( S )
Artigos tcnicos deste tipo, so como tutoriais onde normalmente descrito
um passo a passo com detalhes de implementao, ativao ou quaisquer
alteraes que objetivem o autor do artigo a cri-lo.

B ENCHMARKS E E XPERINCIAS
Este um outro tipo de artigo bastante interessante, onde o autor do artigo,
por necessidade ou ocasionalidade, passou por algum problema ou fez
alguns testes que posteriormente demonstra em seu artigo tcnico.
Geralmente estes artigos so bem interessantes e demonstram situaes do
dia a dia e podem agregar bastante conhecimento quem atua ou possui
ambiente similar ao descrito no artigo.

M V T e c h | 37

SQL Server: Alm do Conceito


Blog Post Collection
O ARTIGO TCNICO EM SI

E STRUTURA
Um artigo tcnico (ou no) bem estruturado muito importante, pois facilita
e contribui para que a leitura fique mais agradvel e entendvel. Se a ideia
escrever muito, este tpico especialmente importante, pois quanto maior
o texto, mais cansativa e desestimulante fica a leitura, caso a mesma no
esteja bem estruturada, sendo o inverso igualmente verdadeiro, quando
mais bem estruturado, melhor e mais agradvel se torna a leitura do mesmo.
Por um texto bem estruturado, entende-se a diviso do mesmo (introduo,
desenvolvimento e concluso), estruturao utilizando-se marcadores,
definies de fontes tradicionais de tamanhos proporcionais e
principalmente a diviso em tpicos e subttulos, determinando exatamente
o assunto que determinado ponto do artigo trata.

L INGUAGEM
No se pode dizer que correto ou incorreto escrever de uma forma
completamente informal ou de forma muito formal. O ideal definir o
pblico alvo que se deseja atingir, e escrever da forma correta para este
pblico alvo. Por exemplo, talvez escrever de forma extremamente formal,
um artigo onde os principais leitores sero jovens universitrios em incio de
carreira, pode tornar a leitura um tanto quanto chata e cansativa. Da mesma
forma, no aconselhado um texto muito informal, quando o pblico alvo
so diretores e presidentes de empresas de Tecnologia, ou outras. Sendo seu
artigo formal ou no, o importante o correto direcionamento do artigo ao
seu respectivo pblico alvo.

P BLICO A LVO
Conforme mencionado anteriormente, alm de escrever da maneira correta
para o pblico alvo correto, preciso conhecer e saber para quem se est

M V T e c h | 38

SQL Server: Alm do Conceito


Blog Post Collection
escrevendo, com isto possvel adequar a linguagem, estrutura e contedo
do seu artigo.

GRAMTICA

E VITE OS ERROS MAIS COMUNS ( DIGITAO , GRIAS , CONCORDNCIA , ETC )


Um dos pontos mais importantes em um artigo tcnico a clareza e
assertividade com que se escreve um texto, relacionado gramtica do
idioma no qual este texto escrito. Se o texto est em portugus por
exemplo, imprescindvel tomar todos os cuidados com erros de
concordncia, grias, neologismos e at mesmo com erros de digitao, que
naturalmente podem aparecer durante a redao do mesmo. Um texto bem
escrito e gramaticalmente correto corrobora muito para que ao final da
leitura, o leitor tenha prestado ateno ao contedo e tenha tido bom
entendimento do que pretendia-se ter passado, do que ficar em mente os
assassinatos ao idioma encontrados durante a leitura.

S OLICITE R EVISES (A MIGOS , C OMUNIDADE , P ARENTES , S R . J OAQUIM )


Uma ferramenta gratuita e muito til a reviso antes da publicao. bem
provvel que uma pessoa que possui um local onde publicar seus artigos
(tcnicos ou no), conhea outras pessoas do meio, que podem ler e avaliar
o texto antes de o mesmo ser publicado. Ainda assim, caso no seja possvel
encontrar algum que possa revisar o texto, possvel solicitar que uma ou
mais pessoas o faam (mesmo no sendo do meio relacionado ao contedo
do artigo).
Se possvel, aconselhvel que sejam feitas revises tcnicas e gramaticais,
assim mitiga-se o risco de incorrees tanto na parte tcnica proposta no
artigo, como tambm a parte gramatical que to importante quanto.
Abaixo, listo alguns pontos importantes com relao algumas principais
preocupaes e com a publicidade quando se est desenvolvendo um artigo
tcnico.

M V T e c h | 39

SQL Server: Alm do Conceito


Blog Post Collection
PRINCIPAIS PREOCUPAES

S EMPRE

Solicite que algum revise seus textos antes de public-los


Cite as fontes das informaes
Pesquise em fontes fidedignas
No assassine o idioma
Deixe claro que o texto sua opinio, no uma verdade absoluta

N UNCA
Escreva com pressa de publicar
Publique um artigo sem pelo menos uma reviso
Copie ou reblogue algo, sem autorizao do autor do texto original
Diga que sua forma a nica maneira existente

P UBLICIDADE
Canais disponveis
Blog Pessoal
Technet Wiki
Facebook (Pages and Profile)
Twitter

M V T e c h | 40

SQL Server: Alm do Conceito


Blog Post Collection
FAA BARULHO
Divulgue sempre seus artigos tcnicos.
Cuidado para no se tornar um spammer ou um chato bloqueado

CONCLUSO

Em resumo, um blog ou canal de textos tcnicos quando bem escrito pode


alavancar uma carreira, tornar seu autor conhecido por seus timos artigos
e consequentemente rendendo bons resultados (convites, empregos,
propostas, networking, etc). Em contrapartida, se o texto no bem escrito
e no toma-se diversos cuidados (alguns mencionados no texto supracitado)
esta exposio pode ter o efeito contrrio e fazer as oportunidades, a fama
e propostas sumirem, visto que voc pode estar mostrando a todos em seu
texto seus pontos fracos (gramtica, conhecimento tcnico, etc).
Eu gostaria ainda de esclarecer que tudo o que foi escrito foi baseado em
minhas preocupaes e minha opinio. De forma alguma a representao
absoluta da verdade. Se voc concorda, discorda ou tem algo a acrescer, ser
muito bem vindo nos comentrios.
Obrigado por chegar at aqui,

Grande abrao,

Edvaldo Castro
http://edvaldocastro.com

M V T e c h | 41

SQL Server: Alm do Conceito


Blog Post Collection

Diego Nogare
www.diegonogare.net

Partition Table
Particionamento de Tabelas

Fala galera, esses dias atrs estava fazendo uma apresentao sobre SQL
Server 2012 e surgiu uma dvida de um dos participantes
sobre particionamento horizontal de tabelas. Decidi procurar alguns
materiais em portugus e no achei muitos, ento resolvi dar minha
contribuio sobre esse assunto.
Bom, os benefcios de se utilizar Partition Table no SQL Server so muitos,
mas antes de falar dos benefcios, vamos criar um banco de dados de
exemplo para simular uma tabela do mundo real e depois entender o que
o Partition Table.
Esse script cria um banco que ir simular uma tabela de visitas de um museu,
imaginando que o museu foi inaugurado no dia 1 de Janeiro de 2012 e hoje
dia 31 de Dezembro, totalizando neste 1 ano de atividades 1 milho de
visitas. Com os prximos sub-captulos vamos criar as parties, separar
esses dados e deixar cada agrupamento (visitas do mesmo ms) em uma
tabela especfica. Depois podemos comparar os prs e contras desta tcnica.

CREATE DATABASE dbMuseu


GO
USE dbMuseu
GO
CREATE TABLE tbVisitas
(id INT IDENTITY(1,1) PRIMARY KEY
,nome VARCHAR(50)
,data DATE)
GO

M V T e c h | 42

SQL Server: Alm do Conceito


Blog Post Collection
INSERT INTO tbVisitas (nome, data)
VALUES (newid(), /*Dados aleatrios para o
nome*/
convert(date, convert(varchar(15),'2012-' +
convert(varchar(5),(convert(int,rand()*12))+1
) + '-' + /* Gerar ms aleatrio */
convert(varchar(5),(convert(int,rand()*27))+1
) /* Gerar dia aleatrio */ )))
GO 1000000

timo, agora que j temos nossa base para simular Vamos entender o que
o particionamento!
O particionamento horizontal de tabelas uma tcnica que utilizamos na
arquitetura
da
estrutura
de
dados,
para
melhorar
a
performance/desempenho/gerenciamento do sistema gerenciador de
banco de dados. Esta tcnica consiste em dividir os dados, baseado em um
parametro, em tabelas e File Groups diferentes.
Para exemplificar, veja na imagem abaixo os dados que estavam na tabela
Visitas foram divididos em 12 tabelas, cada uma armazenando os dados de
um ms especfico. A tabela azul armazena visitas de Janeiro, a
tabela verde armazena de Fevereiro e a tabela laranja armazena visitas de
Dezembro. Porm, a tabela preta representa a consulta de todas as visitas
do ano inteiro

M V T e c h | 43

SQL Server: Alm do Conceito


Blog Post Collection

No decorrer dos prximos sub-captulos, vamos trabalhar em atividades


especficas necessrias para particionar com sucesso essa tabela de visitas
do museu.

C ENRIOS /B ENEFCIOS
Fala galera, uma duvida frequente quando falamos em particionar uma
tabela, : Porque Particionar?! Pensamos em particionamento de tabelas
quando ela possui muitos registros e precisamos melhorar escalabilidade,
performance e gerenciamento. Normalmente desenhamos as tabelas para
armazenar informaes de uma entidade especfica, como Funcionarios,
Vendas ou Produtos. No porque desenhamos e entendemos este modelo
de dados que otimizamos a tabela para receber grande volume J
encontrei por ai, e no foi s uma vez, tabelas com quantidade de dados
significativa e que no tinha nenhum tipo de ndice. Acreditem, triste mas
verdade! Quando falamos de bancos de dados realmente grandes, nos
referimos VLDB (Very Large Database). No regra que um VLDB possua
tabelas que precisam ser particionadas. Para particionar uma tabela um dos
pontos mais importante a se levar em considerao o tempo gasto para
dar manuteno nesta tabela, e no somente a quantidade de registros.
Imaginem o caso de uma tabela de Produtos de um e-Commerce que fica
2h/dia lenta porque est reorganizando/reconstruindo o ndice, ou fica
travada quando esto rodando algum relatrio Esse tipo de tabela pode
ser particionada para melhorar o tempo de resposta das consultas e garantir
que o e-Commerce continue fazendo suas vendas online. Pensando em
relatrios, isso pode causar uma lentido grande no seu RDBMS (Relational
Database Management System) quando tem um ROLAP (Relational On Line
Analytical Processing) realizando agregaes. Se uma tabela com 1 milho
de registros precisa agregar as vendas por ms, o processamento ir
trabalhar com todas as linhas da tabela e far o somatrio. Imaginando este
mesmo cenrio em um ambiente particionado, cada partio faz suas
agregaes e no final do processamento, voc ter uma resposta mais rpida
e seu ambiente continuou respondendo com rapidez. Um outro tipo de
particionamento de tabelas pode ser feito para separar dados quentes e

M V T e c h | 44

SQL Server: Alm do Conceito


Blog Post Collection
histrico. Os dados quentes so os dados que voc trabalha atualmente, por
exemplo, os dados do trimestre atual e os dados de histrico so os dados
dos trimestres passados. Se voc separar os dados da sua tabela a cada 3
meses, voc pode deixar os dados atuais em discos mais nobres do seu
storage (SSD) e os dados de histrico em outros discos menos nobres (SAS
ou SATA). Imagine a necessidade de consultar as vendas do ultimo ano, com
a tabela particionada, voc faria isso sem ter nenhuma concorrencia com as
transaes que esto acontecendo atualmente na tabela.

D EFINIES /T ERMINOLOGIAS
Fala galera, para implementar o particionamento horizontal de tabelas,
importante conhecer as definies e terminologias utilizadas. Para
alinharmos, vou falar do que fundamental para voc entender e aplicar
essa tecnologia nos seus projetos.
Para comear, vamos entender a estrutura de armazenamento do Partition
Table. Esta forma de trabalhar se aplica desde SQL Server 2005 at o 2012,
antes disso, com o SQL Server 7 ou 2000, at onde me lembro, tinha que
fazer manualmente a quebra dos dados nas tabelas particionadas e a
consulta era feita atravs de uma VIEW com UNION ALL de todas as tabelas
particionadas um verdadeiro parto!
Desde o SQL Server 2005, quando criamos uma tabela e/ou ndice no nosso
banco e no definimos onde ele ser armazenado, ele fica no
filegroup default. Porm, podemos criar a tabela e/ou ndice em um partition
scheme. O partition scheme faz um mapeamento de um ou mais filegroups,
mas para armazenar os dados nos arquivos fsicos corretos (nos filegroups)
ele usa o partition function, que por sua vez, contm o algoritmo que
realmente identifica onde determinada linha ser armazenada. A ordem
cronolgica mais ou menos assim:

M V T e c h | 45

SQL Server: Alm do Conceito


Blog Post Collection

Ok, agora que entendemos de forma macro a estrutura de armazenamento,


vamos entender conceitualmente como o SQL Server quebra os dados
baseado em uma coluna da tabela.
Para isso, necessrio definir o Range que o algoritmo de particionamento
ir usar para separar os dados de forma correta e informar o partition
function (que ir armazenar no local indicado). Esse Range atua juntamente
ao Partition Key, que uma coluna nica existente na tabela e utilizada
como separador lgico dos dados. Depois dos dados separados em tabelas
especficas, possvel trabalhar com os dados das tabelas no s fazendo
consultas, mas tambm juntando (Merge) e/ou particionando ainda mais as
tabelas (Split). Tambm usa-se o Switch para converter uma tabela que
estava sendo usada como atual, com dados quentes, para ser entendida
como histrico.

M V T e c h | 46

SQL Server: Alm do Conceito


Blog Post Collection

Pegando como base o database criado no sub-capitulo de Particionamento


de Tabelas, se for separar os dados com base em cada ms, o Partition
Key seria a coluna Data e o Range seria cada perodo que quero utilizar,
baseado em um incio e fim da coleo de dados. Seria algo assim:

Intervalo
1
2

12

Inicio
01/01/2012
01/02/2012

01/12/2012

Fim
31/01/2012
28/02/2012

31/12/2012

Fiquem atentos essas nomenclaturas, a medida que precisarmos usar cada


uma delas vou explicar em detalhes suas caracteristicas e funcionamento.

M V T e c h | 47

SQL Server: Alm do Conceito


Blog Post Collection
C RIANDO F ILEGROUP

Fala galera, mesmo o Filegroups sendo o final do processo de criar a


Partition Table pois onde os dados sero armazenados de fato, vamos crilos primeiro. Depois de criar os filegroups podemos voltar e criar o Partition
Function e o Partition Scheme.
Antes de criar o filegroup, vamos relembrar um pouco de conceito do SQL
Server. Todos os dados de uma tabela so armazenados em um agrupador
chamado Pgina que possui 8Kb de tamanho. Independente de uma pgina
estar com apenas 1 registro, ou totalmente preenchida com dados, ela ocupa
8Kb de tamanho. Outra caracteristica que dentro de uma pgina so
armazenados somente dados de uma mesma tabela. Se neste exemplo
abaixo existisse somente 1 funcionrio e 1 produto, existiriam 2 pginas
criadas. O conjunto de 8 pginas chamado de Extent, que por sinal,
tem 64Kb de tamanho (8Kb de cada uma das 8 pginas).

Mais pra frente vamos entender o porque importante saber o tamanho de


uma Pgina e de um Extent.
Os Databases so criados no filegroup Default, se no for especificado em
qual filegroup deve ser criado. Por padro, no SQL Server 2012, os filegroups

M V T e c h | 48

SQL Server: Alm do Conceito


Blog Post Collection
so armazenados dentro da pasta \Program Files\Microsoft SQL
Server\MSSQL11.SQL2012\MSSQL\DATA com o nome do Database que voc
criou. Se voc quiser especificar o filegroup na hora de criar seu Database,
deve adicionar o cdigo T-SQL junto criao do seu Database. Veja abaixo
a criao do dbMuseu_2 informando o filegroup via cdigo T-SQL.

CREATE DATABASE dbMuseu_2


ON
( NAME = dbMuseu_2,
FILENAME = 'C:\Program Files\Microsoft SQL
Server\MSSQL11.SQL2012\MSSQL\DATA\dbMuseu_2.m
df',
SIZE = 10,
MAXSIZE = 50,
FILEGROWTH = 5 )
LOG ON
( NAME = dbMuseu_log,
FILENAME = 'C:\Program Files\Microsoft SQL
Server\MSSQL11.SQL2012\MSSQL\DATA\dbMuseu_2_l
og.ldf',
SIZE = 5MB,
MAXSIZE = 25MB,
FILEGROWTH = 5MB ) ;
GO

Esta criao do dbMuseu_2 s para exemplificar como especificar o


filegroup na hora da criao do Database, fique a vontade para excluir o
dbMuseu_2, caso tenha criado.
Quando se cria mais de um filegroup por Database, os novos arquivos de
filegroup possuem a extenso .NDF ao invs de .MDF. Tambm temos o
arquivo .LDF que so os arquivos de LOG das transaes que o Database
processa.
Os Databases j criados, tanto o dbMuseu (criado no primeiro sub-capitulo)
quanto o dbMuseu_2 criado agora, possuem apenas 1 Filegroup. Veja na
imagem abaixo estes arquivos fsicos.

M V T e c h | 49

SQL Server: Alm do Conceito


Blog Post Collection

Vamos criar agora outros filegroups para o dbMuseu (criado no primeiro subcapitulo) para poder separar os dados da tabela tbVisitas e utilizar o
propsito destes captulo, o Partition Table!
Primeiro vamos adicionar o nome lgico dos Filegroups ao nosso Database.
Como j temos o dbMuseu criado, vamos alterar o banco de dados ao invs
de criar um novo. Veja o cdigo T-SQL abaixo:

USE MASTER
GO
ALTER DATABASE
[FG2012_JAN]
ALTER DATABASE
[FG2012_FEV]
ALTER DATABASE
[FG2012_MAR]
ALTER DATABASE
[FG2012_ABR]
ALTER DATABASE
[FG2012_MAI]
ALTER DATABASE
[FG2012_JUN]
ALTER DATABASE
[FG2012_JUL]
ALTER DATABASE
[FG2012_AGO]
ALTER DATABASE
[FG2012_SET]
ALTER DATABASE
[FG2012_OUT]

dbMuseu ADD FILEGROUP


dbMuseu ADD FILEGROUP
dbMuseu ADD FILEGROUP
dbMuseu ADD FILEGROUP
dbMuseu ADD FILEGROUP
dbMuseu ADD FILEGROUP
dbMuseu ADD FILEGROUP
dbMuseu ADD FILEGROUP
dbMuseu ADD FILEGROUP
dbMuseu ADD FILEGROUP

M V T e c h | 50

SQL Server: Alm do Conceito


Blog Post Collection
ALTER DATABASE dbMuseu ADD FILEGROUP
[FG2012_NOV]
ALTER DATABASE dbMuseu ADD FILEGROUP
[FG2012_DEZ]
GO

Para confirmar os nomes lgicos adicionados ao seu Database, voc pode ir


at as propriedades do banco, clicando com o boto direito em dbMuseu >>
Properties, e ento nas opes da esquerda, v at Filegroups como na
imagem abaixo, ou ento atravs do cdigo T-SQL:

USE dbMuseu
GO
sp_helpfilegroup
GO

M V T e c h | 51

SQL Server: Alm do Conceito


Blog Post Collection

Pronto, os nomes lgicos esto criados, agora o momento de criar


os arquivos fsicos e associ-los esses nomes lgicos dos filegroups. Para
isso, necessrio realizar outro cdigo DDL de Alter Database, veja esse
cdigo abaixo:
USE MASTER
GO
ALTER DATABASE dbMuseu
ADD FILE
(NAME = 'FG2012_01_JAN'
,FILENAME = 'C:\Program Files\Microsoft SQL
Server\MSSQL11.SQL2012\MSSQL\DATA\FG2012_01_J
AN.ndf')
TO FILEGROUP [FG2012_01_JAN]
GO

M V T e c h | 52

SQL Server: Alm do Conceito


Blog Post Collection
Neste
cdigo
acima,
criamos
fisicamente
o
filegroup FG2012_01_JAN.NDF baseado no nome lgico criado
anteriormente, e que receber somente os dados de Janeiro/2012 quando
particionarmos os dados.
Voltando
para
a
pasta
\Program
Files\Microsoft
SQL
Server\MSSQL11.SQL2012\MSSQL\DATA, podemos ver o arquivo fsico j
criado:

Devemos replicar esse ultimo cdigo de Alter Table para todos os outros
Filegroups que precisamos criar, isso : Fevereiro, Maro, Abril
at Dezembro.
Sempre lembrando de alterar a localizao do arquivo, o nome e o nome do
filegroup.
Para verificar que todos arquivos foram criados, outra alternativa executar
o cdigo T-SQL abaixo:

USE dbMuseu
GO
sp_helpfile
GO

M V T e c h | 53

SQL Server: Alm do Conceito


Blog Post Collection
Nos prximos sub-captulos, vamos criar o Partition Function e o Partition
Scheme.

C RIANDO P ARTITION F UNCTION


Fala galera, logo depois de criar os filegroups e distribuir entre os discos
existentes, hora de criar o Partition Function que sustentar os algoritmos
que faro a quebra dos dados.
Quando se cria o partition function, necessrio definir os limites
condicionais dos perodos. O primeiro ponto que precisa ter ateno
exatamente essa criao dos limites (boundary) informando se o perodo
(range) ter como base de criao os dados do esquerdo (left) ou do lado
direito (right), IMPORTANTE ressaltar que o boundary utilizado fora que o
valor informado ser utilizado naquele range do contexto. Para exemplificar,
vamos criar uma partio que teria os dados anteriores a 30/junho/2012 em
uma partio e a partir de 01/julho2012 em outra.

Para usar o boundary left, a quebra deve usar os dados esquerda da


condio, incluindo-a. Uma outra forma de dizer, que os dados ficariam
em <= 2012-06-30
Veja o cdigo abaixo como ficaria essa partition function com left.
CREATE PARTITION FUNCTION
QuebraPelaEsquerda(date)
AS
RANGE LEFT FOR VALUES ('20120630')

M V T e c h | 54

SQL Server: Alm do Conceito


Blog Post Collection
Para usar o boundary right a quebra ser a direita da condio, com a
condio informada entrando na quebra, outra leitura para isso seria >=
2012-07-01
Veja o cdigo abaixo como ficaria essa partition function com right.

CREATE PARTITION FUNCTION


QuebraPelaDireita(date)
AS
RANGE RIGHT FOR VALUES ('20120701')

Voltando ao cenrio do museu, que estamos utilizando durante todo este


captulo, vamos criar os partition functions baseados nos 12 meses de 2012.
Vou escrever o cdigo para boundary right, mas fique a vontade para
escrever com o left, para estudar. Lembrando que para usar o left, ao invs
de informar o primeiro dia de cada ms, voc deve informar o ultimo dia do
ms anterior.

USE dbMuseu
GO
CREATE PARTITION FUNCTION MuseuPorMes(date)
AS
RANGE RIGHT FOR VALUES ('20120101',
'20120201', '20120301',
'20120401', '20120501', '20120601',
'20120701', '20120801', '20120901',
'20121001', '20121101', '20121201')

Criamos 12 partition functions informando qual a data inicial de cada uma


delas dentro do dbMuseu, isso significa que os dados anteriores a
01/Janeiro/2012 esto armazenados em 1 partio unica, contendo os dados
desde quando comearam a ser inseridos at o dia 31/12/2011. Outro ponto
importante a ser lembrado que os dados acima de 01/12/2012 esto todos

M V T e c h | 55

SQL Server: Alm do Conceito


Blog Post Collection
em uma mesma partio, visto que no existe uma prxima partio que
encerra o range deste grupo iniciado em 1 de Dezembro.
No prximo sub-captulo, finalmente ser criado o partition scheme

C RIANDO O P ARTITION S CHEME


Fala galera, seguindo a sequncia lgica do particionamento, uma vez
os Partition Function criados, voc deve associ-los aos Partition Scheme. O
Partition Scheme responsvel por encaminhar os dados para
os Filegroups corretos, por isso muito importante nomear corretamente os
Filegroups e os Partition Schemes.
Quando fizemos a quebra dos dados no Partition Function MuseuPorMes,
definimos 12 parties (uma para cada ms). Agora sero criados os 13
Partition Scheme para os meses. Voc deve estar se perguntando porque
13 e no 12. A ultima Partition Scheme ir receber os dados acima de
01/12/2012, e ir encaminhar para o Primary Filegroup. Veja o cdigo:

CREATE PARTITION SCHEME MuseuPorMesScheme


AS
PARTITION MuseuPorMes TO
(
[FG2012_01_JAN],[FG2012_02_FEV],[FG2012_03_MA
R]
,[FG2012_04_ABR],[FG2012_05_MAI],[FG2012_06_J
UN]
,[FG2012_07_JUL],[FG2012_08_AGO],[FG2012_09_S
ET]
,[FG2012_10_OUT],[FG2012_11_NOV],[FG2012_12_D
EZ]
,[PRIMARY] )
GO

Lembrando que o MuseuPorMes o nome do Partition Function criado


anteriormente.

M V T e c h | 56

SQL Server: Alm do Conceito


Blog Post Collection
Caso todas as parties estivessem apontando para o mesmo Filegroup, voc
poderia escrever uma sintaxe mais simples, apontando todas as parties
para o Primary Filegroup. Veja como seria esse cdigo:

CREATE PARTITION SCHEME MuseuPorMesScheme


AS
PARTITION MuseuPorMes ALL TO ([PRIMARY])
GO

Por final, voc precisa criar a tabela informando qual ser o Partition
Scheme que ir controlar o armazenamento dos dados. No prximo subcaptulo vamos ver essa criao!

C RIANDO A TABELA
Fala galera, este o ultimo sub-captulo sobre a parte estrutural do Partition
Table, e onde se cria a tabela utilizando os conceitos vistos nos subcaptulos anteriores.
Para conseguirmos comparar o desempenho de uma tabela com os dados
em um unico Filegroup (tbVisitas) e a tabela com todo o Partition Table,
criaremos uma segunda tabela (tbVisitas_2) exatamente com a mesma
estrutura da tabela anterior e vamos popular com os mesmos dados
inseridos anteriormente na tabela inicial.
Veja a criao da tabela, informando o Partition Scheme (veja a linha 5) em
frente ao ON, que pode ser colocado ou no na criao da tabela. Caso no
informe, o SQL Server cria a tabela com o filegroup padro, que geralmente
o primary. Quando informamos um Partition Scheme na criao da tabela,
os dados passam a utilizar o Partition Scheme para escrever no filegroup
correto, que na sequncia consulta o Partition Function para saber qual o
algoritmo de quebra dos dados

M V T e c h | 57

SQL Server: Alm do Conceito


Blog Post Collection
CREATE TABLE tbVisitas_V2
(id INT IDENTITY(1,1)
,nome VARCHAR(50)
,data DATE)
ON MuseuPorMesScheme(data)
GO

E aqui a insero dos dados exatamente igual tabela original:

INSERT INTO TBVISITAS_V2(NOME,DATA)


SELECT NOME,DATA FROM TBVISITAS
GO

Pra fixar a idia, lembre-se da imagem postada no sub-captulo de


definies/terminologias:

Com isso, conseguimos separar em diversos Filegroups, que por sua vez
esto em discos separados, garantindo alta-performance nas consultas
realizadas nesta tabela.
Faam testes com esta tcnica aprendida nestes sub-captulos em seus
projetos e comprovem o desempenho!
C OMPARATIVO DE INSERO DE DADOS EM UMA T ABELA COM C OLUMN S TORE
I NDEX NO SQL S ERVER 2012

Fala galera, o ColumnStore Index um novo formato de ndice que foi


lanado junto ao SQL Server 2012, este ndice usa um padro de compresso

M V T e c h | 58

SQL Server: Alm do Conceito


Blog Post Collection
de dados proprietrio da Microsoft e altera o formato de armazenamento
dos dados nas pginas do ndice. A primeira vez que um registro inserido
no ndice, ele registra o dado bruto, qualquer outra apario deste mesmo
dado dentro do ndice, o SQL faz um apontamento de memria para o
primeiro registro, diminuindo significativamente o tamanho da pgina com
os ndices. Este novo formato de ndice no chegou para substituir os j
convencionais e teis Clustered e Non-Clustered index, ele vem para atender
um outro cenrio. O armazenamento do ColumnStore Index altera a escrita
dos dados do ndice que estamos acostumados a ver em um padro linear
(como a figura abaixo).

Para um formato colunar por isso o nome ColumnStore armazenando


todos os registros da coluna em uma mesma pgina. Uma representao
visual seria como da imagem abaixo:

M V T e c h | 59

SQL Server: Alm do Conceito


Blog Post Collection

Os ganhos de performance com o uso correto do ColumnStore Index varia


entre 10 e 100X. Podendo, em alguns casos reais que j presenciei, chegar a
retornos 400X mais rpidos. Porm o ColumnStore Index no s
maravilhas. A utilizao deste ndice em uma tabela a transforma em Read
Only, impedindo manuteno nos dados j existentes. Este cenrio de dados
como somente leitura nos remete ambientes de Data Warehouse, onde a
informao armazenada sofre manuteno incremental em determinados
momentos do ciclo e normalmente no atualizada ou excluda. Em alguns
casos sendo incrementado somente uma vez por noite, em outros cenrios
somente uma atualizao semanal, em um terceiro podendo ser uma vez por
ms. Isso varia de acordo com a necessidade da rea de negcios. Agora, se
a tabela est em um formato Read Only, como podemos inserir dados
incrementais nela???
Pensando sobre como implementar estes incrementos, vem mente 3
possibilidades. Podemos: 1) desabilitar, inserir e reabilitar o ndice; 2)
remover, inserir e recriar o ndice; ou 3) ento trabalhar com
Particionamento de Tabelas, onde temos as parties com o ndice e uma
tabela onde sero inseridos os dados atuais. Para colocar em comparao
estes trs cenrios, montei um ambiente de teste com aproximadamente
35Milhes de linhas e fiz comparativo entre eles. Veja o comparativo abaixo
entre Logical Read dos trs cenrios, e tambm o tempo necessrio para
realizar cada atividade.

M V T e c h | 60

SQL Server: Alm do Conceito


Blog Post Collection

O teste consistiu em criar uma tabela com 33milhes de registros e aplicar o


ColumnStore Index nesta tabela. Em seguida, adicionar mais 1.6Milhes de
linhas Realizamos o teste no mesmo ambiente 2 vezes, e tiramos a mdia

M V T e c h | 61

SQL Server: Alm do Conceito


Blog Post Collection
tanto de Logical Reads quanto de Elapsed Time do processo. Os resultados
provam que a melhor soluo, disparada, a utilizao de Partition Table.

Caso algum queira simular o processo que utilizei, segue abaixo a criao
do ambiente e a populao das tabelas com menos dados. claro que para
voc simular a mesma coisa que fiz aqui, voc precisa adaptar este cdigo
abaixo para seu cenrio.

/*******************************************/
/*********** CRIAO DO AMBIENTE ***********/
/*******************************************/
CREATE DATABASE ngrSolutionsDW
GO
USE ngrSolutionsDW
GO
/*******************************************/
/*********** LIMPEZA DO AMBIENTE ***********/
/*******************************************/
USE ngrSolutionsDW
GO
DROP SEQUENCE seq_Codigo
GO
DROP TABLE tabelaProducao
GO
DROP TABLE tabelaProducao_v2
GO
DROP PARTITION SCHEME ps_DataAtualizacao
GO
DROP PARTITION FUNCTION pf_DataAtualizacao
GO
/*******************************************/
/********** POPULAO DO AMBIENTE **********/
/*******************************************/
CREATE TABLE tabelaProducao(
id INT NOT NULL
, idOrigem INT NOT NULL
, nome VARCHAR(20) NOT NULL

M V T e c h | 62

SQL Server: Alm do Conceito


Blog Post Collection
, endereco VARCHAR(30) NOT NULL
, dataCadastro date NOT NULL
, dataAtualizacao date NOT NULL
ON [PRIMARY]
GO

ALTER TABLE tabelaProducao WITH CHECK ADD


CONSTRAINT [validarCodigo_V1_Check]
CHECK
(dataAtualizacao >= '2010-01-01' and
dataAtualizacao < '2013-03-01')
GO
ALTER TABLE tabelaProducao CHECK CONSTRAINT
[validarCodigo_V1_Check]
GO
CREATE SEQUENCE seq_Codigo AS INT
INCREMENT BY 1
minvalue 1
maxvalue 10000
GO
/* 1K registros de SETEMBRO 2012 */
insert into tabelaProducao(id, idOrigem,
nome,
endereco, dataCadastro,
dataAtualizacao)
values (next value for seq_Codigo,
convert(int,rand()*100)+1,
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
dateadd(month,-5, convert(datetime,
getdate())),
dateadd(month,-5, convert(datetime,
getdate())))
go 1000
/* 1K registros de OUTUBRO 2012 */
insert into tabelaProducao(id, idOrigem,
nome,
endereco, dataCadastro,
dataAtualizacao)

M V T e c h | 63

SQL Server: Alm do Conceito


Blog Post Collection
values (next value for seq_Codigo,
convert(int,rand()*100)+1,
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
dateadd(month,-4, convert(datetime,
getdate())),
dateadd(month,-4, convert(datetime,
getdate())))
go 1000
/* 1K registros de NOVEMBRO 2012 */
insert into tabelaProducao(id, idOrigem,
nome,
endereco, dataCadastro,
dataAtualizacao)
values (next value for seq_Codigo,
convert(int,rand()*100)+1,
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
dateadd(month,-3, convert(datetime,
getdate())),
dateadd(month,-3, convert(datetime,
getdate())))
go 1000
/* 1K registros de DEZEMBRO 2012 */
insert into tabelaProducao(id, idOrigem,
nome,
endereco, dataCadastro,
dataAtualizacao)
values (next value for seq_Codigo,
convert(int,rand()*100)+1,
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
dateadd(month,-2, convert(datetime,
getdate())),
dateadd(month,-2, convert(datetime,
getdate())))
go 1000

M V T e c h | 64

SQL Server: Alm do Conceito


Blog Post Collection

/* 1K registros de JANEIRO 2013 */


insert into tabelaProducao(id, idOrigem,
nome,
endereco, dataCadastro,
dataAtualizacao)
values (next value for seq_Codigo,
convert(int,rand()*100)+1,
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
dateadd(month,-1, convert(datetime,
getdate())),
dateadd(month,-1, convert(datetime,
getdate())))
go 1000
/* 500 registros de FEVEREIRO 2013 */
insert into tabelaProducao(id, idOrigem,
nome,
endereco, dataCadastro,
dataAtualizacao)
values (next value for seq_Codigo,
convert(int,rand()*100)+1,
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
getdate(), getdate())
go 500
SET STATISTICS IO ON; SET STATISTICS TIME ON
GO
/*******************************************/
/*********** DISABLE / REBUILD *************/
/*******************************************/
/************ CRIAO DO INDEX *************/
/*******************************************/
CREATE NONCLUSTERED COLUMNSTORE INDEX
[idx_csi_tabelaProducao]
ON tabelaProducao ( id, nome, endereco,
dataCadastro, dataAtualizacao )
GO

M V T e c h | 65

SQL Server: Alm do Conceito


Blog Post Collection

/*******************************************/
/******** INSERIR NA TABELA DE PROD ********/
/*******************************************/
/* +1 em FEVEREIRO 2013 */
-- Forar o erro por causa que a tabela est
com ColumnStore Index
insert into tabelaProducao(id, idOrigem,
nome,
endereco, dataCadastro,
dataAtualizacao)
values (next value for seq_Codigo,
convert(int,rand()*100)+1,
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
getdate(), getdate())
/*******************************************/
/************ DISABLE / REBUILD ************/
/*******************************************/
ALTER INDEX idx_csi_tabelaProducao ON
tabelaProducao DISABLE
GO
ALTER INDEX idx_csi_tabelaProducao ON
tabelaProducao REBUILD
GO
/*******************************************/
/************ POPULAR A TABELA *************/
/*******************************************/
ALTER INDEX idx_csi_tabelaProducao ON
tabelaProducao DISABLE
GO
insert into tabelaProducao(id, idOrigem,
nome,
endereco, dataCadastro,
dataAtualizacao)
values (next value for seq_Codigo,
convert(int,rand()*100)+1,
substring(convert(varchar(40),newid()),1,20),

M V T e c h | 66

SQL Server: Alm do Conceito


Blog Post Collection

substring(convert(varchar(40),newid()),1,30),
dateadd(month,-4, convert(datetime,
getdate())), getdate())
go 1000
ALTER INDEX idx_csi_tabelaProducao ON
tabelaProducao REBUILD
GO
/*******************************************/
/************** DROP / CREATE **************/
/*******************************************/
/************ CRIAO DO INDEX *************/
/*******************************************/
CREATE NONCLUSTERED COLUMNSTORE INDEX
[idx_csi_tabelaProducao]
ON tabelaProducao ( id, nome, endereco,
dataCadastro, dataAtualizacao )
GO
/*******************************************/
/******** INSERIR NA TABELA DE PROD ********/
/*******************************************/
/* +1 em FEVEREIRO 2013 */
-- Forar o erro por causa que a tabela est
com ColumnStore Index
insert into tabelaProducao(id, idOrigem,
nome,
endereco, dataCadastro,
dataAtualizacao)
values (next value for seq_Codigo,
convert(int,rand()*100)+1,
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
getdate(), getdate())
/*******************************************/
/************** DROP / CREATE **************/
/*******************************************/
DROP INDEX [idx_csi_tabelaProducao] ON
tabelaProducao
GO

M V T e c h | 67

SQL Server: Alm do Conceito


Blog Post Collection

CREATE NONCLUSTERED COLUMNSTORE INDEX


[idx_csi_tabelaProducao]
ON tabelaProducao ( id, nome, endereco,
dataCadastro, dataAtualizacao )
GO
/*******************************************/
/************ POPULAR A TABELA *************/
/*******************************************/
DROP INDEX [idx_csi_tabelaProducao] ON
tabelaProducao
GO
insert into tabelaProducao(id, idOrigem,
nome,
endereco, dataCadastro,
dataAtualizacao)
values (next value for seq_Codigo,
convert(int,rand()*100)+1,
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
dateadd(month,-4, convert(datetime,
getdate())), getdate())
go 1000
CREATE NONCLUSTERED COLUMNSTORE INDEX
[idx_csi_tabelaProducao]
ON tabelaProducao ( id, nome, endereco,
dataCadastro, dataAtualizacao )
GO
/*******************************************/
/************* PARTITION TABLE *************/
/*******************************************/
/********** CRIAO DAS PARTIES **********/
/*******************************************/
CREATE PARTITION FUNCTION
[pf_DataAtualizacao](date) AS RANGE RIGHT
FOR VALUES ('2012-09-01','2012-10-01','201211-01',
'2012-12-01','2013-01-01','201302-01','2013-03-01')

M V T e c h | 68

SQL Server: Alm do Conceito


Blog Post Collection
GO
CREATE PARTITION SCHEME [ps_DataAtualizacao]
AS PARTITION [pf_DataAtualizacao] ALL TO
([PRIMARY])
GO
/*******************************************/
/************ CRIAO DOS INDEX ************/
/*******************************************/
CREATE CLUSTERED INDEX [idx_DataCodigo] ON
tabelaProducao(DataAtualizacao)
ON ps_DataAtualizacao(dataAtualizacao)
GO
CREATE NONCLUSTERED COLUMNSTORE INDEX
[idx_csi_tabelaProducao]
ON tabelaProducao ( id, nome, endereco,
dataCadastro, dataAtualizacao )
GO
/*******************************************/
/******** INSERIR NA TABELA DE PROD ********/
/*******************************************/
/* +1 em FEVEREIRO 2013 */
-- Forar o erro por causa que a tabela est
com ColumnStore Index
insert into tabelaProducao(id, idOrigem,
nome,
endereco, dataCadastro,
dataAtualizacao)
values (next value for seq_Codigo,
convert(int,rand()*100)+1,
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
getdate(), getdate())
/*******************************************/
/******** CRIAO DA SEGUNDA TABELA ********/
/*******************************************/
CREATE TABLE tabelaProducao_V2 (id INT NOT
NULL, idOrigem int NOT NULL,

M V T e c h | 69

SQL Server: Alm do Conceito


Blog Post Collection
nome VARCHAR(20) NOT NULL, endereco
VARCHAR(30) NOT NULL,
dataCadastro date NOT NULL,
dataAtualizacao date NOT NULL)
GO
ALTER TABLE tabelaProducao_V2 WITH CHECK ADD
CONSTRAINT[validarCodigo_V2_Check] CHECK
(dataAtualizacao >= '2013-02-01' and
dataAtualizacao < '2013-03-01')
GO
/*******************************************/
/************ CRIAO DOS INDEX ************/
/*******************************************/
CREATE CLUSTERED INDEX [idx_DataCodigo]
ON tabelaProducao_v2(DataAtualizacao) ON
[PRIMARY]
GO
/*******************************************/
/********* MOVIMENTAO DOS DADOS **********/
/*******************************************/
-- Conta os registros
SELECT COUNT(0) [TOTAL], min(dataAtualizacao)
[MENOR],
max(dataAtualizacao) [MAIOR] FROM
tabelaProducao
GO
SELECT COUNT(0) [TOTAL], min(dataAtualizacao)
[MENOR],
max(dataAtualizacao) [MAIOR] FROM
tabelaProducao_v2
GO
-- Movimenta os dados
ALTER TABLE tabelaProducao SWITCH PARTITION 7
TO tabelaProducao_v2
GO
-- Conta os registros
SELECT COUNT(0) [TOTAL], min(dataAtualizacao)
[MENOR],

M V T e c h | 70

SQL Server: Alm do Conceito


Blog Post Collection
max(dataAtualizacao) [MAIOR] FROM
tabelaProducao
GO
SELECT COUNT(0) [TOTAL], min(dataAtualizacao)
[MENOR],
max(dataAtualizacao) [MAIOR] FROM
tabelaProducao_v2
GO
/* Fevereiro na TABELA 2 */
insert into tabelaProducao_V2(id, idOrigem,
nome,
endereco, dataCadastro,
dataAtualizacao)
values (next value for seq_Codigo,
convert(int,rand()*100)+1,
substring(convert(varchar(40),newid()),1,20),
substring(convert(varchar(40),newid()),1,30),
getdate(), getdate())
go 10
-- Conta os registros
SELECT COUNT(0) [TOTAL], min(dataAtualizacao)
[MENOR],
max(dataAtualizacao) [MAIOR] FROM
tabelaProducao
GO
SELECT COUNT(0) [TOTAL], min(dataAtualizacao)
[MENOR],
max(dataAtualizacao) [MAIOR] FROM
tabelaProducao_v2
GO
CREATE NONCLUSTERED COLUMNSTORE INDEX
[idx_csi_tabelaProducao]
ON tabelaProducao_v2 ( id, nome, endereco,
dataCadastro, dataAtualizacao )
GO
ALTER TABLE tabelaProducao_V2 switch to
tabelaProducao partition 7

M V T e c h | 71

SQL Server: Alm do Conceito


Blog Post Collection
GO
-- Conta os registros
SELECT COUNT(0) [TOTAL], min(dataAtualizacao)
[MENOR],
max(dataAtualizacao) [MAIOR] FROM
tabelaProducao
GO
SELECT COUNT(0) [TOTAL], min(dataAtualizacao)
[MENOR],
max(dataAtualizacao) [MAIOR] FROM
tabelaProducao_v2
GO

Bom divertimento em seus testes!

M V T e c h | 72

SQL Server: Alm do Conceito


Blog Post Collection

Demetrio Silva
demetriosilva.wordpress.com

Tuning no SharePoint e SQL Server com o Developer


Dashboard
Tunin no SharePoint com Developer Dashboard

INTRODUO

Apesar do nome sugerir, esta ferramenta no especfica para


desenvolvedores. Developer Dashboard um recurso do SharePoint que
ajuda os desenvolvedores a rastrear problemas de performance em
componentes customizados ou no, dentro uma pgina.
Seu uso muito comum por desenvolvedores, pois possibilita que os
mesmos repassem as informaes das consultas SQL aos DBAs, para anlise
e
possvel
tuning.
A pgina do dashboard carregada no endereo do site, acrescentando
/_layouts/15/devdash.aspx
ao
final.
Tempo que a pgina levou para carregar, quais componentes foram
carregados, as consultas SQL executadas ( durao, plano de execuo, etc),
correlation id, logs ULS so exemplos de informaes exibidas no dashboard.
Por padro, este recurso desabilitado e este artigo vai mostrar como
configurar e habilitar esta feature. Vale lembrar que o Developer Dashboard
no pode ser usado na Central Admin.

M V T e c h | 73

SQL Server: Alm do Conceito


Blog Post Collection
C ONFIGURAO
O Developer Dashboard requer que o Service Application Usage & Health
Data Collection esteja configurado. Os passos abaixo mostram como
verificar se o recurso est ou no configurado:
1 No menu iniciar, abra a console SharePoint 2013 Management Shell
conforme figura 1

M V T e c h | 74

SQL Server: Alm do Conceito


Blog Post Collection
Figura 1 Abrir console PowerShell
2 Com a console aberta, execute o script abaixo conforme figura 2

Figura 2 Script
O script acima tenta criar o Service Application. Caso o mesmo j exista,
mesmo com outro nome, ele gera um erro.
O prximo passo habilitar o Developer Dashboard. Copie e cole o script
abaixo na mesma console do passo 2 e tecle enter:
$service =
[Microsoft.SharePoint.Administration.SPWebService]::ContentService
$dd = $service.DeveloperDashboardSettings
$dd.DisplayLevel = "On"
$dd.Update()
Obs.: para desativar o Developer Dashboard basta executar novamente o
script acima, trocando $dd.DisplayLevel = "On" por $dd.DisplayLevel =
"Off".
Por questes de performance, aps realizar o throubleshooting, desabilite
o Developer Dashboard.

M V T e c h | 75

SQL Server: Alm do Conceito


Blog Post Collection

Veja a execuo do script na figura 3:

Figura 3 Habilitando o Developer Dashboard

Visualizando o Developer Dashboard


Neste momento, j temos o Developer Dashboard configurado. Os passos
abaixo mostram como visualizar os dados na pgina, bem como, ilustra
algumas
de
suas
funcionalidades.
1 Abra qualquer site da Farm. Neste exemplo, usamos o site
http://palestras2013. No canto superior direito, clique no cone Iniciar
painel
de
desenvolvimento
conforme
figura
4

Figura

Iniciar

painel

M V T e c h | 76

de

desenvolvimento

SQL Server: Alm do Conceito


Blog Post Collection
2 Aps o passo anterior, ser aberto um pop-up igual ao da figura 5

Figura

pop-up

do

painel

Na guia Solicitaes, podemos ver cada requisio s pginas no


SharePoint. Basta clicar na solicitao desejada para que o painel mostre as
informaes sobre a mesma. No exemplo abaixo, clicamos na chamada
pgina http://palestras2013/SitePages/Como Usar esta
Biblioteca.aspx?AjaxDelta=1&isStartPlt1=1405695726064, conforme figura
6

M V T e c h | 77

SQL Server: Alm do Conceito


Blog Post Collection

Figura 6 Pgina requisitada


Na Figura 6, dentro da aba Informaes do Servidor temos dois grids:
a) Estatsticas da Solicitao Com um resumo da solicitao. Exibe
informaes como Hora de Incio, Durao Total para carregar a pgina,
Servidor, Usurio, etc.
b) Estatsticas Agregadas - Nela podemos ver o resumo das consultas SQL
executadas, exibindo o nmero de consultas, durao total das consultas,
etc.
Seguindo para a aba ULS, podemos ver todas as entradas no log
referentes pgina que estamos analisando. Isso fantstico, uma vez que
o painel j faz o filtro no log e nos mostra tudo que est ocorrendo na
pgina e foi registrado no log.
Na figura 7, podemos ver o log ULS

M V T e c h | 78

SQL Server: Alm do Conceito


Blog Post Collection

Figura 7 ULS
Outra guia interessante a SQL. Nela podemos ver o tempo de execuo
de cada consulta, o plano de execuo, comando T-SQL, estatsticas de IO e
algumas outras informaes teis.
A figura 8 mostra a guia SQL:

Figura 8 SQL

M V T e c h | 79

SQL Server: Alm do Conceito


Blog Post Collection
Para visualizar mais informaes sobre a consulta, basta clicar no nome da
mesma. A figura 9 mostra as informaes exibidas ao clicar na consulta
SELECT t1.[Tim:

Figura 9 Informaes da consulta

Ao clicar em plano de execuo, tambm podemos ver e/ou salvar o plano


gerado
para
a
consulta.
Existem diversas outras abas no painel que mostram informaes teis. Para
mais informaes acesse o link: http://technet.microsoft.com/ptbr/library/jj219701(v=office.15).aspx.

CONCLUSO

Este artigo mostrou como configurar o Developer Dashboard, uma


ferramenta essencial para os desenvolvedores em SharePoint. Tambm
mostramos
algumas
de
suas
funcionalidades.

M V T e c h | 80

SQL Server: Alm do Conceito


Blog Post Collection
Esta apenas uma das diversas maneiras que o SharePoint nos fornece para
analisar o ambiente e ajustar a performance da Farm.

M V T e c h | 81

SQL Server: Alm do Conceito


Blog Post Collection

Acessando dados do SharePoint com PowerPivot


INTRODUO

um cenrio muito comum as empresas adotarem o SharePoint como


ferramenta de colaborao e uma das verticais do SharePoint so os sites.
Dentro dos sites, temos vrias listas e bibliotecas, que armazenam reunies,
cadastros
de
clientes,
tarefas
dentre
outros
dados.
Com os dados j armazenados, uma necessidade muito comum gerar
relatrios dos dados das listas. Existem vrias formas de gerar relatrios de
listas e uma delas atravs do PowerPivot, que ser o foco deste artigo.
Este artigo usar uma funcionalidade do SharePoint que expe os dados da
lista em forma de Atom feed e como importar os dados Atom Feed para
dentro do data model PowerPivot.

R EQUISITOS
necessrio instalar o runtime ADO.NET nos servidores WFE Web FrontEnd da Farm. Mais informaes aqui ou nos links abaixo:
http://go.microsoft.com/fwlink/?LinkId=221066: Windows Server 2008 R2
http://go.microsoft.com/fwlink/?LinkId=195068: Windows Server 2008

C OMO FUNCIONA
Usaremos os dados do banco de dados adventureworks2012, onde
neste outro artigo, os dados da tabela person foram exportados para Excel e
importados no SharePoint, criando assim uma lista no SharePoint com os
dados
da
planilha
do
Excel.
O acesso aos dados ser realizado pela REST Interface, que permite acesso

M V T e c h | 82

SQL Server: Alm do Conceito


Blog Post Collection
s listas e bibliotecas do SharePoint no formato de relational data service.
Neste caso, as operaes de leitura, atualizao, criao e excluso de itens
so feitas atravs da SharePoint Foundation REST, que prov vrias
operaes para os Web Services RESTFull. Todas mapeadas diretamente
para
GET,
POST,
PUT
e
DELETE
HTTP
Verbs.
A
URL
para
acesso

REST
tem
o
seguinte
padro http://NomeDoSiteSharePoint/_vti_bin/ListData.svc, onde, nos
exemplos
o
site
usado
(NomeDoSiteSharePoint)
se
chama http://palestras2013/, logo, a URL dos exemplos ter o
formato http://palestras2013/_vti_bin/ListData.svc.
Ao acessar a REST Interface do site de exemplo a tela abaixo exibida:

(Figura

REST

Interface

do

site

http://palestras2013/)

Para acessar os dados de uma lista especfica, basta adicionar o nome da lista
no
final
da
URL,
deixando-a
assim
http://palestras2013/_vti_bin/ListData.svc/Categorias/Categorias.
Onde
Categorias o nome da lista que foi importada da base

M V T e c h | 83

SQL Server: Alm do Conceito


Blog Post Collection
AdventureWorks2012

para

SharePoint.

O contedo da lista pode ser visto na Figura 2 e o resultado do REST para


esta
lista
pode
ser
visto
na
Figura
3.

(Figura

Lista

M V T e c h | 84

de

Categorias)

SQL Server: Alm do Conceito


Blog Post Collection
(Figura

Lista

de

Categorias

Atom

Feed)

I MPORTAR PARA O P OWER P IVOT NO E XCEL

Para realizar a importao da lista no PowerPivot do Excel, basta abrir a


janela do PowerPivot e na guia "From Data Service" clicar em From OData
Data
Feed
conforme
Figura
4.

(Figura

Selecionar

fonte

de

dados)

Na tela seguinte, em Data Feed Url, informe a Url da lista que deseja acessar
via REST. Neste caso, http://palestras2013/_vti_bin/ListData.svc/Categorias.
A
figura
5
ilustra
o
exemplo:

M V T e c h | 85

SQL Server: Alm do Conceito


Blog Post Collection

(Figura

Conexo

do

PowerPivot

ao

Feed)

Clique em next, finish e a tela de importao ser exibida conforme abaixo.

(Figura

Finalizando

importao)

Por fim, a figura 7 mostra os dados da lista do SharePoint j importados para

M V T e c h | 86

SQL Server: Alm do Conceito


Blog Post Collection
dentro

(Figura

do

PowerPivot.

Dados

importados)

A partir deste ponto possvel usar os dados da lista dentro do PowerPivot


e usufruir de todas as funcionalidades do mesmo.
Exportar do SharePoint para o PowerPivot
Caso a Farm e o Site Collection que voc esteja usando j tenha o PowerPivot
configurado, a importao da lista para o PowerPivot ainda mais simples.
Basta selecionar a opo "Exportar como Feed de Dados" na lista desejada
conforme
figura
8.

M V T e c h | 87

SQL Server: Alm do Conceito


Blog Post Collection

(Figura 8 Exportando lista do SharePoint para o PowerPivot)


Aps clicar na opo Exportar como Feed de Dados selecione a opo "abrir"
que fica no fim da tela. Caso o tipo de extenso no esteja associado ao Excel,
selecione
abrir
com
->
Excel.

(Figura
Habilite

9
a

conexo

Abrir
de

Feed
dados

M V T e c h | 88

com

conforme

Excel)
Figura

10.

SQL Server: Alm do Conceito


Blog Post Collection

(Figura

10

Habilitar

conexo

de

dados)

Na tela a seguir, marque a opo "Only Create Connection", caso queira


apenas importar os dados neste momento. Por padro, o Excel importa os
dados para o PowerPivot e cria uma Table. Note que a opo "Add this data
to the Data Model" est marcada. Isso indica que os dados sero importados
para
o
PowerPivot.

M V T e c h | 89

SQL Server: Alm do Conceito


Blog Post Collection

(Figura

11

Selecionar

tipo

de

importao)

Por fim, acesse a guia PowerPivot e veja que o Data Model foi exportado para
o
Excel.

M V T e c h | 90

SQL Server: Alm do Conceito


Blog Post Collection

(Figura 12 Dados exportados)

CONCLUSO

Este artigo mostra uma das muitas formas possveis de gerar relatrios
usando os dados das listas do SharePoint. Aps importar os dados, fica bem
fcil criar relatrios complexos e dinmicos usando PowerPivot, Excel,
PowerView e PowerMap.

M V T e c h | 91

SQL Server: Alm do Conceito


Blog Post Collection

Configurar envio de e-mail no SharePoint / SQL


Server com o GMAIL
Neste artigo irei mostrar como configurar o envio de e-mail atravs do
SharePoint/SQL Server utilizando contas do gmail.
A ideia do post mostrar como configurar o relay para envio de e-mail em
aplicaes que no suportam autenticao smtp. Alguns exemplos de
ferramentas so Reporting Services, ArcServe Backup, SharePoint, etc.. Para
estas aplicaes a configurao de e-mail no possvel atravs de contas
que requerem autenticao para enviar mensagens.
Bem, vamos l. Para realizar esta configurao ns precisamos configurar o
relay de e-mails no Windows Server atravs do IIS, usando SMTP Server:

P ASSO 1: C ONFIGURAR O SMTP S ERVER NO W INDOWS 2008.


No Server Manager, v em Add Features:

M V T e c h | 92

SQL Server: Alm do Conceito


Blog Post Collection
Na guia seguinte, escolha SMTP Server e deixe todas as configuraes
padro:

Confirme para adicionar os servios necessrios:

M V T e c h | 93

SQL Server: Alm do Conceito


Blog Post Collection
Deixe as demais opes com o valor padro e clique em next at a aba final
onde tem a opo de instalar.
Aps instalado, feche o Server Manager e abra o IIS 6.0: Menu iniciar / IIS /
Enter.
Com o IIS aberto, expanda o n Local Computer e clique em propriedades do
SMTP Virtual Server:

V na guia access e clique em Relay:

M V T e c h | 94

SQL Server: Alm do Conceito


Blog Post Collection

Configure os PCs liberados para enviar e-mails atravs deste Relay. No meu
caso, liberei para todos da rede:

M V T e c h | 95

SQL Server: Alm do Conceito


Blog Post Collection

Salve, volte para a guia propriedades e acesse a guia Delivery:

M V T e c h | 96

SQL Server: Alm do Conceito


Blog Post Collection

Clique em Outbound Security e selecione a opo Basic Authentication.


Informe seu e-mail do Gmail, senha e marque a opo TLS:

M V T e c h | 97

SQL Server: Alm do Conceito


Blog Post Collection

Novamente no menu Delivery, acesse a opo Outbound Connections e


mude a porta para 587 conforme abaixo e clique em OK:

M V T e c h | 98

SQL Server: Alm do Conceito


Blog Post Collection

Mais uma ves no menu Delivery, selecione a opo advanced e em Smart


Host informe o SMTP do Gmail e clique em OK:

Feche a tela clicando em OK e reinicie o IIS:

M V T e c h | 99

SQL Server: Alm do Conceito


Blog Post Collection

Para testar no SharePoint, abra a Central Admin do Sharepoint e Acesse o


menu System Settings e na guia Outgoing E-mail Settings configure conforme
abaixo:

Pronto. Aps isso seu SharePoint est pronto para enviar e-mails de
notificaes para listas, etc.

M V T e c h | 100

SQL Server: Alm do Conceito


Blog Post Collection

Marcel Inowe
4sqlserver.wordpress.com

Dicas sobre o banco de dados do Protheus(Totvs)


Ol pessoal,
Esses dias meu amigo Leandro Ribeiro (http://www.sqlleroy.com
|@sqlleroy) solicitou no Twitter dicas sobre o banco de dados do Protheus e
como eu dou manuteno no banco de dados desse produto, percebi que eu
sabia vrios detalhes que poderiam ser teis para quem est comeando a
trabalhar com o Protheus agora.
Para quem no conhece o Protheus um dos maiores ERPs do mundo, ele
desenvolvido pela empresa brasileira Totvs onde h alguns anos lder de
mercado nacional. A grande vantagem do Protheus que alm dele ser bem
completo ele customizvel, ou seja, voc compra a licena do sistema e pode
contratar um desenvolvedor para customiz-lo a seu gosto, j imaginou isso?
J pensou se voc pudesse fazer isso com qualquer software que comprasse
ou utilizasse? Pois , por a d para sentir o poder do produto e d para
comear a perceber o porque ele to usado no mercado nacional, mas
claro que nem tudo so flores e obvio que esse produto tem seus pontos
fracos, algumas particularidades e exatamente para discutir isso que
escrevi esse post.

V AMOS AS DICAS :
Quase sempre o banco de dados se chama DADOSADV ou pelo menos
comea com DADOS. No me pergunte o motivo, pois eu no sei;
A aplicao no acessa o banco de dados diretamente ela usa uma camada
intermediria chamada Top Connect. O Top Connect quase sempre
instalado no mesmo servidor que o banco de dados, porm h casos em que
ele instalado em uma mquina exclusiva e ento a aplicao se conecta ao
Top e o Top se conecta ao SQL Server;

M V T e c h | 101

SQL Server: Alm do Conceito


Blog Post Collection
O Protheus multiempresa, porm ao contrrio do que estamos
acostumado a ver nas modelagens onde a empresa identificada com um
campo dentro de cada tabela, o banco do Protheus cria uma tabela para cada
empresa at a verso 10 do ERP, ento se o teu cliente tiver mais de uma
empresa aberta trabalhando no mesmo banco de dados, para cada empresa
ter uma tabela de cliente, produto, nota fiscal e assim suscetivamente.
Agora imaginem uma construtora do ramo imobilirio que para cada
incorporao construda tem que ser aberto um CNPJ. J pensou se ela tiver
mais de 100 empreendimentos construdos ou em construo? O banco
passar de 100 mil tabelas facilmente!
A partir da verso 11 do Protheus j possvel criar as empresas dentro da
mesma tabela o que diminui significativamente o nmero de tabelas dentro
do banco de dados. Essa dica da verso 11 do Protheus foram dadas pelos
amigos Bruno e Luiz Carlos nos comentrios do post.
O nome das tabelas no ultrapassam 6 caracteres e so representados da
seguinte maneira: 3 primeiros caracteres a famlia que aquela tabela
pertence, os 2 prximos caracteres representa a empresa que aquela tabela
pertence e o ltimo caractere reservado ao sistema, por exemplo a tabela
de cliente da empresa 01 a SA1010, da empresa 02 a SA1020 onde SA1
a famlia da tabela, 01 e 02 representa a empresa e o 0 no final reservado.
Como assim famlia ? Exemplo, cliente SA1, fornecedor SA2 e assim por
diante. A Totvs considera que Cliente e Fornecedor pertencem mesma
famlia;
O campo chave primria das tabelas sempre o mesmo, ou seja, todas as
tabelas tem um campo chamado R_E_C_N_O_ que auto-incrementado
pelo Top Connect e a PK das tabelas;
Os registros das tabelas nunca so deletados fisicamente. Todas as tabelas
contm um campo chamado D_E_L_E_T_ e quando algum exclu um
registro no sistema, no banco de dados esse campo preenchido com um *,
ento sempre que for fazer qualquer select lembrem-se de desprezar os
registros deletados colocando na condio where D_E_L_E_T_ = , ou
D_E_L_E_T_ <> *. Esse conceito de excluso lgica foi herdado do DBF;

M V T e c h | 102

SQL Server: Alm do Conceito


Blog Post Collection
No existe campo DateTime nas tabelas. Todos os campo data so
VARCHAR(8), nunca so nulos e so sempre preenchidos com 8 caracteres
em branco para informar que esto vazios;
No existe campo NULL. Se o campo for numrico ele preenchido com zero
e se for String/Char preenchido com espaos em branco. Em ambos os
casos o preenchimento feito via Constraint Default. Agora imaginem a
quantidade de Constraint que cada tabela tem!;
Muito cuidado ao criar ndices nas tabelas, pois se voc criar em uma ter
que criar em todas, por exemplo: Se criar um ndice na tabela de cliente
SA1XX0 lembre-se de replicar esse ndice para as demais tabelas de cliente
caso tenha;
O Protheus trabalha com um dicionrio de dados prprio onde so definidas
as tabelas, campos e ndices ento em uma atualizao de verso feita uma
checagem do dicionrio de dados com a estrutura do banco de dados e tudo
que no estiver definido no dicionrio ser apagado, seja campo, ndice ou
tabela, portanto ao criar um ndice utilizado em um trabalho de Tuning eu
aconselho a criar uma rotina que diariamente verifica a existncia desse
ndice e ento caso no exista mais crie-o novamente. Eu costumo colocar
tudo dentro do step de um job que diariamente consulta a sys.indexes pelo
nome;
Nunca crie um campo em uma tabela sem antes passar para o dicionrio de
dados do Protheus, pois ao abrir uma tela que use a tabela onde o campo foi
criado, essa tela ir travar por no ter o campo no dicionrio;
O desempenho das consultas no so grande coisa, pois a maioria dos
desenvolvedores Protheus no tem grandes habilidades e conhecimento
sobre indexao, ento sempre bom dar uma checada nas consultas mais
lentas e dar um help para a galera de desenvolvimento;
Uma forma de ganhar espao em disco com o banco do Protheus usar a
compresso de dados a nvel de pgina caso o SQL Server seja Enterprise. Em
testes realizados na tabela SB1(Produtos) com 28000 produtos,
comprimindo apenas a tabela passou de 72 MB para 6 MB, ou seja, uma taxa
de compresso de 91.66%;

M V T e c h | 103

SQL Server: Alm do Conceito


Blog Post Collection
Os bancos geralmente so enormes ento vlido pensar em uma estratgia
de particionamento das tabelas;
ndices no usados e duplicados no excesso e sim regra, ento vlido
analisar isso e repassar para os desenvolvedores. Nunca apague um ndice
sem antes apagar no dicionrio, pois as telas fazem essa verificao tambm
em sua abertura e caso no encontre no banco elas travaro;
O Top Connect no funciona em cluster devido ao hardlock que quem
licencia o Protheus e como em alguns casos ele instalado no mesmo
servidor do banco de dados, no ser possvel colocar ele no Service and
Application do Cluster e quando ocorrer um Failover ser necessrio reiniciar
o servidor de licena que fica geralmente em outro servidor, seno ele no
voltar ao ar e a aplicao no abrir;
No possvel fazer uma replicao merge das tabelas, devido fato da
replicao merge adicionar um campo de controle de unicidade chamado
rowguid e caso tenha um campo na tabela do banco e no tenha no
dicionrio do Protheus isso causa srios impactos. Mesmo que no houvesse
o impeditivo do campo rowguid, muitas tabelas ultrapassam 246 colunas e
seria impossvel replicar com merge devido o limite de 246 colunas por
artigo;
Devido o padro das tabelas do Protheus no terem campos NULL e todos
serem preenchidos com uma Constraint Default isso impede que as tabelas
sejam colocadas In-Memory a.k.a Hekaton que o novo recurso do SQL
Server 2014. possvel desde que todas as Constraints Defaults sejam
excludas e os campos que so Not Null passem a ser Null, porm isso
implicaria em uma grande mudana na modelagem do banco e os efeitos
colaterais nesse tipo de mudana so incontveis;
Normalmente os bancos so muito grandes, ento a rotina de manuteno
de ndices se torna uma tarefa difcil e quase impossvel para a rotina do
Maintenance Plan do SQL Server, portanto vlido usar rotina prpria ou de
terceiros como a rotina do Ola Hallengren.
Bom galera espero que essas dicas sejam teis para todos. Conforme eu for
me lembrando de mais coisas eu vou atualizando o post.
*Leandro Ribeiro | blog: sqlleroy.com | twitter: @sqlleroy

M V T e c h | 104

SQL Server: Alm do Conceito


Blog Post Collection

Marcos Freccia
marcosfreccia.wordpress.com

Importando arquivos excel usando o SSIS


Ol pessoal,
Hoje recebi uma dvida do amigo Raphael Wanderley (@raphaelwsantos)
sobre como importar um arquivo do Excel para o SQL Server. Na
oportunidade eu mencionei a ele para utilizar o SQL Server Integration
Services (SSIS), pois muito mais simples de ser feito.
Ento, abaixo vou demonstrar como realizar a importao de arquivos
utilizando o SSIS.

Crie um novo projeto do tipo Integration Services Project conforme a


imagem abaixo.

M V T e c h | 105

SQL Server: Alm do Conceito


Blog Post Collection
Voc dever agora arrastar o componente Data Flow Task, pois dentro
desse passo que vamos adicionar as fontes e destinos para realizar a cpia.

De um duplo clique no componente e uma nova aba ir aparecer. Expanda a


area Other Source e arraste o componente Excel Source. Expanda a area
Other Destinations e arraste o componente OLE DB Destination. Por fim,
conecte atravs da linha azul os dois componentes conforme a imagem
abaixo.

M V T e c h | 106

SQL Server: Alm do Conceito


Blog Post Collection
De um duplo clique no componente Excel Source e depois crie uma nova
conexo.

Escolha o caminho do arquivo Excel que deseja importar, qual a verso do


seu arquivo Excel e tambm se a primeira linha do documento contm as
colunas e no dados.

Para trabalhar com a arquitetura 64bit, voc deve realizar o download


do Microsoft Access Database Engine 2010 Redistributable. Baixe a verso
64bit

M V T e c h | 107

SQL Server: Alm do Conceito


Blog Post Collection
O prximo passo escolher qual aba (Sheet) voc deseja importar.

Agora, de um duplo clique em OLE DB Connection Manager e clique em


New para criar a conexo com o banco de dados.

Crie a conexo com o banco de dados e confirme a operao.

M V T e c h | 108

SQL Server: Alm do Conceito


Blog Post Collection

Enquanto configura o destino dos seus dados, voc tem a opo de escolher
uma tabela j existe, ou criar uma nova tabela para receber os dados a serem
importados. Neste exemplo vamos criar uma nova tabela.

M V T e c h | 109

SQL Server: Alm do Conceito


Blog Post Collection

Feito a criao da tabela, voc j estar pronto para realizar a importao do


arquivo.
Agora, voc poder iniciar a execuo do pacote pressionando a tecla F5 ou
pressionando o boto conforme a imagem abaixo.

O pacote sendo executado com sucesso, voc dever ver isso no fluxo criado.

M V T e c h | 110

SQL Server: Alm do Conceito


Blog Post Collection

Verificando o SQL Server, os arquivos foram importados corretamente.

Pronto, voc j fez a sua primeira soluo em SSIS. Agora basta voc seguir
um tutorial de como agendar pacotes do SSIS no SQL Server Agent.

M V T e c h | 111

SQL Server: Alm do Conceito


Blog Post Collection
Espero que tenham gostado e estarei montando mais tutoriais desse tipo
explicando pequenas funcionalidades.

M V T e c h | 112

SQL Server: Alm do Conceito


Blog Post Collection

T-SQL no SQL Server 2012 Parte 1


Ol pessoal,
O intuito dessa srie de posts que vou iniciar agora mostrar tudo de novo
que temos na parte de T-SQL no SQL Server 2012. Antes de iniciarmos bom
deixar frisado que o intuito aqui no mostrar nada mirabolante, mas sim o
SIMPLES! Ento esqueam de ver algo avanado, o que vocs iro ver aqui
o bsico.
Para no criar posts extensos que nos cansam de ler, vou faz-lo por partes.
Hoje vamos falar de:
Execute WITH RESULT SETS
Sequence
1) EXECUTE WITH RESULT SETS.
Esse novo recurso surgiu no SQL Server 2012 como uma necessidade de
formatao de nossos conjuntos de dados, provenientes de uma stored
procedure. Ento sua explicao e demonstrao bastante simples.
Pegamos um result set que est vindo como sada de uma procedure e
mostramos para o usurio da maneira que necessitamos atravs desse result
set personalizado.

V AMOS VER COMO FUNCIO NA ?


Tenho aqui uma simples procedure.
USE AdventureWorksDW2012
GO
CREATE PROCEDURE spGetSalesAmout
AS
SELECT FirstName ,
SalesAmount
FROM
FactInternetSales AS fact
JOIN
DimCustomer
AS
cust
fact.CustomerKey = cust.CustomerKey

M V T e c h | 113

ON

SQL Server: Alm do Conceito


Blog Post Collection
Temos aqui duas possibilidades de deixar nosso
result set mais amigvel.
1) Mudar diretamente no cdigo T-SQL
2) Utilizar o recurso WITH RESULT SETS.
Vamos ver como funciona?
execute spGetSalesAmout
WITH RESULT SETS
(
([Primeiro Nome] varchar(20),
[Total de Vendas] money)
);

Como vemos aqui, podemos at trocar o tipo de dados que ser retornado.
Vamos agora ver o resultado.

M V T e c h | 114

SQL Server: Alm do Conceito


Blog Post Collection

Em questes de usabilidade esse recurso seria interessante onde no


podemos mudar o cdigo da consulta T-SQL, por muitas vezes estar
capturando dados de outros sistemas.
Como podemos ver um recurso muito simples e que pode nos ajudar
bastante.
2) SEQUENCE
Recurso esse muito conhecido no Oracle a sequence, um objeto
responsvel por gerar nmeros sequencias. Ai voc me pergunta: Mas j

M V T e c h | 115

SQL Server: Alm do Conceito


Blog Post Collection
temos o identity. Correto, porem o objeto Sequence vem para abrir mais
possibilidades de utilizao e como a mesma um objeto permite outros
tipos de gerenciamento que no temos no campo identity.

C OMO UTILIZAR ?

P ASSO 1: C RIAO DA S EQUENCE .


A criao da sequence muito simples e com apenas alguns comandos j
conseguimos criar.

CREATE SEQUENCE DemoSequence


START WITH 1
INCREMENT BY 1;

At ai tambm podemos utilizar o identity no campo, j que conseguimos ter


o incio e realizar incrementos personalizados.

C OMO UTILIZAMOS A SEQUENC E ?


CREATE TABLE Demo1
(
id INT PRIMARY KEY ,
nome VARCHAR(100)
)
GO
INSERT INTO Demo1
VALUES ( NEXT VALUE FOR dbo.DemoSequence,
'Marcos Freccia' )

O comando NEXT VALUE FOR dbo.DemoSequence o que faz o nmero ser


gerado e automaticamente incrementado.

M V T e c h | 116

SQL Server: Alm do Conceito


Blog Post Collection

Se realizarmos mais uma insero teremos.

Como eu disse anteriormente, a Sequence um objeto ento a possibilidade


de gerenciamento e de usabilidade maior por exemplo.
INSERT INTO Demo1
VALUES ( NEXT VALUE FOR dbo.DemoSequence +
2, 'Marcos Freccia' )

M V T e c h | 117

SQL Server: Alm do Conceito


Blog Post Collection
R ESULTADO .

Podemos criar tambm sequences que possuem um limite mximo de


nmeros a serem gerados.
CREATE SEQUENCE DemoSequence2
START WITH 1
INCREMENT BY 1
MAXVALUE 5;

Vamos realizar apenas uma demonstrao.


CREATE TABLE Demo2 ( id INT, nome
VARCHAR(100) )
GO
INSERT INTO Demo2
VALUES ( NEXT VALUE FOR dbo.DemoSequence2,
'Marcos Freccia' )
GO 5
SELECT
FROM

*
Demo2

M V T e c h | 118

SQL Server: Alm do Conceito


Blog Post Collection

Vamos realizar apenas mais uma insero.

Como puderam ver, a nossa sequence no deixou que realizssemos mais


inseres de dados no campo.
Bom pessoal por hoje era isso, espero que tenham gostado e no decorrer do
tempo estarei mostrando mais funcionalidades em T-SQL no SQL Server
2012.

M V T e c h | 119

SQL Server: Alm do Conceito


Blog Post Collection

T-SQL no SQL Server 2012 Parte 2 Paginao de


dados
Ol pessoal,
Atualmente aplicaes web fazem o uso de uma funcionalidade at ento
presente apenas a nvel de desenvolvimento que o recurso de realizar a
paginao dos dados, ou seja, mostrar dados em tela pouco a pouco e no
simplesmente retornar tudo, assim evitando problemas de performance.
Foi pensando nisso que no SQL Server 2012 foi implementado um novo
recurso juntamente a clausula Order By utilizando dois recursos de nome
OFFSET e FETCH.
Para iniciarmos o entendimento sobre essa funcionalidade, precisamos ter
em mente dois termos que sero utilizados na clausula Order By.
OFFSET: Especifica o nmero de linhas a ignorar antes de iniciar o retorno
dos dados propostos pela consulta. Esse valor sempre dever ser maior ou
igual a 0(zero)
FETCH: Especifica o nmero de linhas a retornar depois que a clausula
OFFSET foi processada. Esse valor sempre dever ser um inteiro constante
ou uma expresso que maior ou igual a 1.
Bom, vamos parar com a parte terica e vamos demonstrar a parte pratica
dessa nova funo.
Apenas alguns scripts de criao de base de dados e insero de dados.

USE master
GO
CREATE DATABASE DB_OrderByClause
GO
USE DB_OrderByClause
GO
CREATE TABLE tblPaginacao
(
id INT IDENTITY ,

M V T e c h | 120

SQL Server: Alm do Conceito


Blog Post Collection
nome VARCHAR(100)
)
GO
INSERT
VALUES

INTO tblPaginacao
( 'Registro 1' ),( 'Registro 2' ),
( 'Registro 3' ),( 'Registro 4' ),
( 'Registro 5' ),( 'Registro 6' ),
( 'Registro 7' ),( 'Registro 8' ),
( 'Registro 9' ),( 'Registro 10' ),
( 'Registro 11' ),( 'Registro 12' ),
( 'Registro 13' ),( 'Registro 14' ),
( 'Registro 15' ),( 'Registro 16' ),
( 'Registro 17' ),( 'Registro 18' ),
( 'Registro 19' ),( 'Registro 20' )

C ONSULTA 1
SELECT *
FROM
tblPaginacao
ORDER BY id
OFFSET 5 ROWS

M V T e c h | 121

SQL Server: Alm do Conceito


Blog Post Collection

Na primeira consulta apenas a clausula OFFSET foi especificada, ou seja,


como foi falado anteriormente o OFFSET ignora o nmero de linhas
desejadas. No exemplo estamos realizando o OFFSET de 5 registros, ento
normal que a consulta seja retornada a partir do registro de nmero 6.

C ONSULTA 2

SELECT *
FROM
tblPaginacao
ORDER BY id
OFFSET 5 ROWS
FETCH NEXT 10 ROWS ONLY

M V T e c h | 122

SQL Server: Alm do Conceito


Blog Post Collection

Nessa segunda consulta foi especificado a clausula OFFSET e FETCH, ou seja,


de acordo com a consulta ser ignorada os cinco primeiros registros e apenas
ir retornar os prximos dez registros, por isso a clausula FETCH NEXT 10
ROWS ONLY.
Bom pessoal como vocs puderam ver apenas duas demonstraes bsicas
de como utilizar esse novo recurso no SQL Server 2012.
Espero que tenham gostado e at a prxima.

M V T e c h | 123

SQL Server: Alm do Conceito


Blog Post Collection

Ivan Lima
www.ivanglima.com

Inside The Machine Introduo


Quando voc pensa na memria do seu servidor, qual a primeira coisa que
te vem cabea? Gigabytes? Terabytes? Enfim, espao? E quando voc
pensa em desempenho, a primeira coisa que voc pensa so os Gigahertz da
CPU?
Nessa srie de artigos vamos explorar o subsistema de memria de um ponto
de vista um pouco diferente: o foco ser a interao entre ele e a CPU.
Falaremos do desempenho da memria e como ela pode afetar e afeta!
o desempenho como um todo do seu servidor, e o que voc pode e no
pode fazer a respeito em relao ao seu banco de dados (ou qualquer outra
aplicao).

V ELOCIDADE DO PROCE SSADOR TUDO ?


Se voc no conhece Martin Thompson, recomendo adicionar o blog ao seu
leitor de RSS favorito e acompanhar o que ele escreve e palestra. Ele
definitivamente uma das grandes referncias no assunto de HPC (High
Performance Computing) e baixa latncia e vamos utilizar alguns testes
escritos por ele (e alguns meus) durante essa srie, ento nada mais justo do
que comear fazendo referncia a uma frase sua: The real design action is
in the memory sub-systems. [2]
Voc j percebeu que ultimamente tm sido bastante falado sobre a
velocidade dos processadores e como seu desempenho parou de evoluir nos
ltimos anos em favor do aumento da quantidade de cores? Quem
desenvolve software com certeza j ouviu que deve aprender
desenvolvimento de software com paralelismo para no arriscar ficar sem
emprego no futuro. A famosa frase the free lunch is over tem sido repetida
diversas vezes nas ltimas conferncias mundo fora desde que o guru de

M V T e c h | 124

SQL Server: Alm do Conceito


Blog Post Collection
C++ Herb Sutter escreveu o seu artigo homnimo em 2005 para o respeitado
journal Dr. Bobbs [1].
De fato a frequncia dos processadores parou de subir, principalmente
devido s questes de economia de energia e dissipao de calor, como
possvel observar claramente no grfico abaixo tirado do artigo de Sutter:

M V T e c h | 125

SQL Server: Alm do Conceito


Blog Post Collection

Intel CPU Trends 1970-2010. Fonte: The Free Lunch Is Over, Herb Sutter

Mas olhar apenas para os GHz no conta toda a histria.

Linha

Modelo

Ops/Sec

Ano de Lanamento

Core 2 Duo

P8600 @ 2.40GHz

1434

2008

Xeon

E5620 @ 2.40GHz

1768

2010

Core i7

i7-2677M @ 1.80GHz

2202

2011

Core i7

i7-2720QM @ 2.20GHz

2674

2011

Podemos observar na tabela acima que o desempenho geral do CPU continua subindo, mesmo que a
frequncia esteja, de certa forma, estagnada. Medimos esse desempenho atravs de IPCs, ou Instructions
per Cycle.
Ou seja, em um processador de 2 GHz capaz de fazer o retirement de at 4 instrues por ciclo (IPC), como
o caso da microarquitetura Nehalem, no caso ideal o seu desempenho pode chegar a 8 bilhes de
instrues por segundo! Nada mal.

M V T e c h | 126

SQL Server: Alm do Conceito


Blog Post Collection

Single Threaded Performance Trends 1995-2011 [3]

M V T e c h | 127

SQL Server: Alm do Conceito


Blog Post Collection

Ento se o desempenho das CPUs efetivamente continua subindo (apesar de claramente em um ritmo
menor) mesmo que os clocks se mantenham estveis, quem o responsvel por segurar o desempenho geral
dos sistemas?
Refazendo a pergunta anterior de outra forma Em um workload onde o gargalo no se encontra nem em
I/O nem na CPU, o que impede o seu processador de realizar o trabalho mais rapidamente?
Voc provavelmente j deve ter matado a charada: no acesso memria, ou o que chamamos de latncia.
Mas esse fato no parece ser muito bvio primeira vista: memria no s uma questo de quantidade.

putz...

Em relao ao custo de acesso ao disco, a latncia do acesso memria irrisrio.


A memria, porm, o que previne que o seu sistema rode em seu desempenho mximo. Isso ocorre pois o
acesso memria significativamente inferior velocidade do processador, e essa diferena s cresceu
ainda mais nas ltimas dcadas. Esse fenmeno chamado de Memory Wall, termo cunhado no paper [4].
Se pudssemos trabalhar com dados apenas nos registradores, a memria com a menor latncia no CPU,
o nosso processador poderia utilizar todo o seu potencial computacional. Infelizmente, principalmente em
servidores de bancos de dados, isso est muito longe da realidade. comum trabalharmos com working sets
de dezenas ou centenas de GB. E por isso pagamos o custo de acesso memria o tempo todo. Enquanto
esse acesso ocorre, o processador precisa ficar esperando pelos dados at que ele possa voltar a trabalhar,
efetivamente gastando ciclos de clock toa. Um cache miss pode custar centenas de ciclos de clock do
processador, tempo que ele poderia gastar realizando operaes ao invs de esperar por dados para serem
processados.
Com o fim da era de crescimento contnuo dos clocks dos processadores os engenheiros tm evoludo as
microarquiteturas a fim de amenizar o impacto da latncia do acesso memria principal do sistema. Os
processadores se utilizam de diversos artifcios para esconder essa latncia, e assim diminuir a penalidade
causada pela disparidade entre o desempenho entre eles. Um deles o Hyper-Threading (SMT), tpico de
um prximo artigo.

REFERNCIAS:

[1] Sutter The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in Software
[2] Thompson
Mythbusting modern hardware
to gain Mechanical Sympathy
[3]
Moore

Data
Processing
in
Exascale-class
Computing
Systems
[4] Wulf, McKee Hitting the Memory Wall: Implications of the Obvious

M V T e c h | 128

SQL Server: Alm do Conceito


Blog Post Collection

Inside the Machine Processadores


INTRODUO

Se voc no viu a primeira parte da srie, sugiro que leia antes de continuar, pois nessa parte vamos seguir
a linha de pensamento apresentado anteriormente.

P ROCESSADORES
J que vamos falar sobre mecanismos internos das CPUs precisamos escolher alguma implementao, ou
microarquitetura especfica como ponto de partida.
Escolhi a microarquitetura Nehalem [1] pelo simples fato de que tenho processadores baseados nessa
microarquitetura tanto nos servidores do ambiente onde trabalho quanto no meu notebook.
Segundo a Intel, o desenvolvimento dessa microarquitetura custou aproximadamente 12 bilhes de dlares,
incluindo US$ 9 bilhes na construo das fbricas (fabs), US$ 1 bilho para o design do processo de
fabricao de 45 nanmetros em material dieltrico High-k [11], e US$ 2 bilhes no design da
microarquitetura em si [3].
Outra microarquitetura, chamada Westmere a verso reduzida (shrink) da microarquitetura Nehalem,
seguindo o padro tick-tock de fabricao da Intel [2]. Esse tem um processo de fabricao de 32nm. A
atualizao das fabs para esse shrink custou Intel mais US$ 7 bilhes [10].
Apesar da Intel j ter lanado novas microarquiteturas desde ento Sandy Bridge, Ivy Bridge e o recmanunciado Haswell as microarquiteturas Nehalem e Westmere so bastante comuns nos servidores que se
encontram em produo hoje.

O VERVIEW DA M ICROARQUITETURA
Nehalem foi uma microarquitetura particularmente importante em relao a tecnologias Intel. Foi nessa
microarquitetura que a Intel reintroduziu o hyper-threading ao seus processadores, aps remover a
funcionalidade nos processadores baseados na microarquitetura Core. Outra tecnologia importante
introduzida pelo Nehalem foi o uso de um interconnect entre os processadores, similar ao que a AMD j
vinha oferecendo, para remover o gargalo do acesso memria com o Front-Side Bus (FSB). Chamado
de QuickPath Interconnect (QPI), a Intel criou a tecnologia visando recuperar o mercado perdido para a AMD
durante o perodo.
Falaremos sobre o QPI no futuro, quando entrarmos no assunto de Non-Uniform Memory Access, ou NUMA.

M V T e c h | 129

SQL Server: Alm do Conceito


Blog Post Collection

Primeiro chip Nehalem, Cortesia Intel

C ORE E U NCORE
Na terminologia dos designers e engenheiros de processadores, os processadores so divididos entre Cores
e Uncore.
Cores so desenhados como blocos reutilizveis de lgica e hardware e no mudam entre um modelo e
outro.
Os cores Nehalem e Westmere possuem 64 KB de cache L1 e 256 KB de cache L2 cada. O cache L3
compartilhado entre todos os caches do chip, e o seu tamanho dependente dos modelos.
O Uncore, por outro lado, so os componentes que no fazem parte do Core. Dependendo da literatura que
voc ler isso inclui L3, I/O, IMC e QPI. Outros separam os componentes, portanto teramos Uncore, QPI, IMC,
etc.
O Uncore pode mudar (e efetivamente muda) de um modelo para outro, mesmo entre modelos da mesma
microarquitetura.

P LANTA
Alm disso, os Cores rodam em frequncias e voltagens independentes entre si. O Uncore tambm roda em
uma frequncia independente do restante dos cores. Nos slides da Intel, eles se referem ao Uncore e outros
componentes de forma distinta, mas ao se referirem frequncia e voltagem, chamam todos de Uncore
tambm.

M V T e c h | 130

SQL Server: Alm do Conceito


Blog Post Collection

Particionamento de voltagem e frequncia do Nehalem, Cortesia Intel

A diferena na frequncia entre Cores e Uncore tem impacto direto no desempenho da mquina, atravs de
funcionaliades como Turbo Boost e SpeedStep.
Quando estiver abordando um assunto especfico de cada modelo (uncore) darei preferncia ao Xeon E78870, o modelo com qual trabalho. Conhecido como Westmere-EX, este o absoluto top de linha da Intel
em arquitetura x86 nesse ciclo de lanamentos.

X EON E7
O Xeon E7-8870 possui aproximadamente 2.6 bilhes (!) de transstores
em uma pastilha de 513 mm; quatro portas QuickPath Interconnect (fullwidth) em 3.2 GHz rodando a 25.6 GB/s full-duplex; 2 controladoras de
memria DDR3 on-chip dual-channel de 10.83 GB/s cada, totalizando 4
canais e 43.3 GB/s; 10 cores 20 threads em com hyper-threading por
socket rodando a uma frequncia base de 2.4 GHz. As 4 portas QPI
permitem escalar at 8 sockets em um nico sistema e chegar at 2 TB
de memria com DIMMs de at 32 GB.

Processador Intel Xeon E7, Cortesia Intel

M V T e c h | 131

SQL Server: Alm do Conceito


Blog Post Collection

Chip Westmere, Cortesia Intel

Note o aumento de cores na imagem do chip Westmere em relao ao Nehalem apresentado no incio do
post. Se olhar atentamente, poder perceber que se tratam dos mesmos cores, apenas replicados mais 2
vezes. possvel perceber tambm o aumento nos bancos de cache, abaixo dos cores.

C ORE I 5 460M
J o meu notebook tem uma configurao bem mais modesta e organizado de uma forma um pouco
diferente, apesar de ser baseado na mesma microarquitetura.
um Intel Core i5 460M, codinome Arrendale, rodando a 2.53 GHz. Possui aproximadamente 382 milhes
de transstores divididos entre 2 cores e o LLC (aka L3) de 4 MB, porm somente 3 MB so habilitados para
esse modelo. A controladora de memria (IMC) e o grfico ficam em outro chip no mesmo package,
interligados com o chip do processador atravs de uma interface QuickPath Interconnect. A controladora de
memria possui 2 canais DDR3 de 1.333 MHz e suportam DIMMs de at 8 GB.
Na imagem abaixo podemos visualizar o chip do processador (88mm) e o chip Northbridge de aprox. 177
milhes de transstores (114mm) no mesmo package.

Intels Core i5 Arrandale CPU, Cortesia Intel

No diagrama de blocos podemos ver claramente a topologia entre o processador e o GPU, conectados por
uma interface QPI:

M V T e c h | 132

SQL Server: Alm do Conceito


Blog Post Collection

Diagrama de blocos dos Clarkdale/Arrandale, Cortesia Arstechnica

M OORE S L AW
Como eu falei no artigo anterior o clock dos processadores parou de subir mas o desempenho dos cores
continua subindo, embora no no mesmo ritmo que subia anteriormente. Como isso possvel? Atravs da
lei de Moore.
Gordon Moore [4] co-fundador da Intel, e a lei leva o seu nome pois ele foi o autor da frase que dizia que
o nmero de transistors em cada processador dobraria a cada 2 anos. Existem diversas verses e
interpretaes das palavras ditas por Moore. Segue a frase original [5]:
The complexity for minimum component costs has increased at a rate of roughly a factor of two per year.
Certainly over the short term this rate can be expected to continue, if not to increase. Over the longer term,
the rate of increase is a bit more uncertain, although there is no reason to believe it will not remain nearly
constant for at least 10 years.
A frase pode se encontrada no artigo escrito por Moore [14], mas sem entender a relao entre defeitos,
custo e integrao na fabricao de chips a frase difcil de ser digerida. Uma verso que gosto e que modifica
ao mnimo a frase foi publicada no Arstechnica, em 2008 [13]:
The number of transistors per chip that yields the minimum cost per transistor has increased at a rate of
roughly a factor of two per year.
Esse o sentido original da frase, e a percepo do mercado de chips em geral nas ltimas dcadas. A frase
foi dita em 1965, e apesar de Moore ter previsto a continuidade por 10 anos, a lei continua em vigor at hoje.

M V T e c h | 133

SQL Server: Alm do Conceito


Blog Post Collection

Grfico do nmero de transstores ao longo da histria, Cortesia Wikipedia

M V T e c h | 134

SQL Server: Alm do Conceito


Blog Post Collection
Essa quantidade extra de transstores utilizada pelos engenheiros para aumentar a eficincia dos
processadores. Com cada ciclo de lanamentos, os processadores ficam mais e mais complexos.
Em alguns modelos Nehalem, por exemplo, quase 60% desses transstores so dedicados aos caches,
principalmente no cache L3 [12]. O restante utilizado para adicionar mais lgica e mais funcionalidades,
aumentando assim a complexidade dos chips.

C OMPLEXIDADE

Vista area de Shangai, China

Para se ter uma ideia da complexidade desses


processadores, basta imaginar que a cidade mais
populosa da China, Shangai, possui aproximadamente
16 milhes de habitantes, enquanto o processador Xeon
E7-8870,
como
dito
anteriormente,
possui
aproximadamente 2.6 bilhes de transstores. Ou seja,
se cada morador correspondesse a um transstor,
precisaramos de 162 Shangais e meia. Isso o dobro de
toda a populao da prpria China, o pas mais populoso
do mundo.

GPGPU
Uma forma alternativa de utilizar esses transstores seria a criao de ncleos pouco complexos, porm em
quantidades muito maiores do que vistos hoje, como por exemplo um processador com dezenas ou centenas
de cores.
Na verdade esse tipo de arquitetura existe e muito utilizada. encontrada em GPUs, que possuem centenas
de ncleos simples (em relao aos ncleos de uma CPU). Em geral, esses ncleos no servem para fazer o
processamento de qualquer tipo de cdigo e operao e portanto no substituem os processadores comuns,
mas podem ser teis para algoritmos onde possvel fazer paralelismo massivo do processamento. Existem
vrias vertentes de desenvolvimento de dispositivos, linguagens e ferramentas para aproveitar melhor esses
recursos como o NVIDIA CUDA, OpenCL e mais recentemente o C++AMP da Microsoft, do qual j falei no
meu blog. Em (http://ivanglima.com/c-em-2012/)
Esse tipo de processamento, chamado de General-purpose computing on graphics processing units, ou
GPGPU, ainda no utilizado pelos SGBDs, mas j existem pesquisas nesse sentido, como pode ser visto em
[8] e [9].

C ACHE
Agora que j fizemos uma introduo bsica s CPUs, no prximo artigo vamos nos aprofundar um pouco no
assunto dos caches.

REFERNCIAS

[1]
[2]

http://en.wikipedia.org/wiki/Nehalem_(microarchitecture)
http://en.wikipedia.org/wiki/Intel_Tick-Tock

M V T e c h | 135

SQL Server: Alm do Conceito


Blog Post Collection
[3] http://forwardthinking.pcmag.com/pc-hardware/283044-intel-looks-ahead-nehalem-larrabee-and-atom
[4]
http://en.wikipedia.org/wiki/Gordon_Moore
[5]
http://en.wikipedia.org/wiki/Moores_Law
[6]
http://www.xbitlabs.com/articles/cpu/display/core-i7-920-overclocking_3.html
[7]
http://www.extremetech.com/extreme/133541-intels-64-core-champion-in-depth-on-xeon-phi
[8]
http://sacan.biomed.drexel.edu/vldb2012/program/?volno=vol5no13&pid=1004&downloadpaper=1
[9]
http://wiki.postgresql.org/images/6/65/Pgopencl.pdf
[10]
http://asia.cnet.com/blogs/intel-invests-us7-billion-in-32nm-westmere-cpu-manufacturing62114335.htm
[11]
http://www.intel.com/pressroom/kits/advancedtech/doodle/ref_HiK-MG/high-k.htm
[12]
http://upcommons.upc.edu/e-prints/bitstream/2117/13932/1/hybrid_NUCA-hipc11.pdf
[13]
http://arstechnica.com/gadgets/2008/09/moore/
[14]
http://www.computerhistory.org/semiconductor/assets/media/classic-paperspdfs/Moore_1965_Article.pdf

M V T e c h | 136

SQL Server: Alm do Conceito


Blog Post Collection

Inside The Machine - Hyper-Threading (SMT) e SQL Server


O principal fator que vai definir o impacto do HT no seu ambiente o seu workload tanto positivamente
quanto negativamente.
A prpria Intel limita o ganho terico do HT a 30% [1]. Isso , no melhor do melhor dos casos, o mximo de
desempenho que voc vai ganhar com HT 30%. pouco? No acho. Mas o que eu acho que HT muitas
vezes confundido como uma funcionalidade de desempenho quando na realidade uma funcionalidade que
visa melhorar a eficincia do seu processador. Ele vai utilizar alguns ciclos a mais que teriam sido perdidos
caso no houvesse um pipeline substituto pronto para entrar em cena. No h ganho, e sim controle de
perda.
HT nada mais do que a duplicao de alguns componentes do pipeline do ncleo, permitindo que esse, no
melhor caso, no pare totalmente de trabalhar quando houver uma dependncia ainda no disponvel
durante a execuo, como um acesso de memria que resultou em cache miss, por exemplo.

Pipeline (SMT)

M V T e c h | 137

SQL Server: Alm do Conceito


Blog Post Collection

T EORIA E PRTICA

Ok, mas saindo um pouco da teoria e indo para a parte prtica, muitas coisas comeam a influenciar na
brincadeira.
O prprio escalonamento do Windows (e de tabela o do SQL Server) afeta o desempenho do sistema com
o HT habilitado ou no. Por exemplo, se o algoritmo do scheduler no levar em conta o fato de dois
ncleos lgicos (por falta de nome melhor) compartilharem os mesmos ALUs o seu desempenho vai
piorar sensivelmente quando o scheduler escalonar duas threads no mesmo ncleo fsico ao invs de
ncleos fsicos distintos.
Esse cenrio era muito comum nos primrdios do Windows Server [2], quando este no fazia distino
entre ncleos fsicos e lgicos. Ainda vemos algo parecido hoje nos processadores oriundos da
microarquitetura Bulldozer da AMD, que utiliza uma tecnologia que tambm afeta o comportamento do
pipeline, mas no exatamente uma implementao do SMT. Os schedulers no estavam preparados
para lidar com isso durante o lanamento dos processadores dessa microarquitetura, fazendo a AMD
sofrer em alguns benchmarks [3].
Trocando em midos, existem muitos fatores e o impacto no desempenho final pode ser bem maior do
que os 30% tericos, tanto positivamente quanto negativamente.

M ITO
Existe um mito que o Hyper-Threading o mal encarnado para o SQL Server, devido a diversos fatores,
incluindo os citados acima. Um dos causadores (no intencional) desse rumor foi o Slava Oks [4] (ex-time
de produto, SQLOS), e se voc quiser ver um timo exemplo de como fazer o HT no funcionar, sugiro que
leia o seu post e execute os testes voc mesmo.

P ROCESSADORES
Agora vamos para a questo de desempenho de processadores
Observando o processo do SQL Server (sqlservr.exe) podemos notar que ele possui callstacks bastante
profundas, de pelo menos uns 8 nveis desde o incio do processamento de uma consulta, e muitos
branches ao longo da execuo dessa consulta, mesmo simples. Servidores OLTP, em geral, costumam ter
um working set de GBs de dados em memria e processar pequenas partes dessa massa cada segundo,
de forma aleatria. Na teoria [5], esses tipos de cenrios so excelentes candidatos a fazer um bom uso
do SMT e tambm so bastante influenciados pelo tamanho dos caches do processador, a latncia de
acesso da sua memria RAM e a eficincia do branch predictor. Esses fatores podem at mesmo
influenciar mais que o prprio clock do seu processador Nada de comprar processadores olhando
apenas os GHz!
M V T e c h | 138

SQL Server: Alm do Conceito


Blog Post Collection
Workloads de OLAP e aplicaes cientficas , por outro lado, tendem a ser mais sensveis fora bruta
do processador.
Enfim No final das contas, a nica coisa que vai te dizer se o HT pode ou no beneficiar o seu ambiente
o teste. So fatores demais que influenciam no resultado final para fazer uma previso para qualquer
direo. Se voc tiver um processador com HT, teste seu workload com e sem o HT habilitado e colete
mtricas que te diro qual prefervel.
No caso do seu processador no possuir a funcionalidade, s posso dizer que no se preocupe com isso.
H formas mais prticas e diretas de influenciar o desempenho do seu ambiente.

REFERNCIAS:

[1] http://en.wikipedia.org/wiki/Simultaneous_multithreading#Modern_commercial_implementations
[2]
http://www.hardwaresecrets.com/article/Activating-the-Hyper-Threading/20
[3] http://www.hardwarecanucks.com/news/cpu/microsoft-tries-again-second-win-7-bulldozer-hotfixnow-available/
[4]
http://blogs.msdn.com/b/slavao/archive/2005/11/12/492119.aspx
[5] http://www.cs.washington.edu/research/smt/papers/smtdatabase.pdf

M V T e c h | 139

SQL Server: Alm do Conceito


Blog Post Collection

Fabiano Neves Amorim


www.blogfabiano.com

Join reordering e Bushy Plans


INTRODUO

Normalmente o otimizador de consultas no considera bushy plans (dois operadores se unem ao


resultado de outros joins). Isso significa que o SQL pode no produzir bons planos para alguns tipos de
consultas. Hints (dicas), por si s tambm no iro fazer isso. Para tal otimizao, uma mgica mais
poderosa necessria.

J OIN REORDERING E B USHY P LANS


Pessoal, atualmente estou sofrendo com meu conflito existencial de otimizador sucks, deixa eu explicar
melhor.
Quando voc comea a trabalhar e estudar muito sobre o otimizador de consultas do SQL Server (ou de
qualquer outro DB) voc passa por vrios conflitos existenciais, so eles:
Olha se eu apertar ctrl+l aparece um monte de desenhinhos
Preciso aprender a ler um plano de execuo (j no chama mais de desenhinhos)
Mas que raios esse operador faz?
Por qu??? Mas por qu?????
Conor Cunningham (http://blogs.msdn.com/b/conor_cunningham_msft/) gente boa demais!
Aaaaa, estou comeando a entender
Esse Paul White (http://sqlblog.com/blogs/paul_white/default.aspx) insano!
UAU! Que esperto que o otimizador !
Odeio esse Paul White (inveja pura!)
Opa, estimou errado!
Ummm, acho que d pra melhorar esse plano!
Ummm, acho que d pra melhorar esse plano 2!
Ummm, acho que d pra melhorar esse plano 3!
M V T e c h | 140

SQL Server: Alm do Conceito


Blog Post Collection
Estatsticas sucks!
Joins sucks!
Otimizador sucks!
...

Pois bem, eu estou no nvel otimizador sucks .


No sei o que esta acontecendo (pode ser apenas uma fase), mas ultimamente 60% das consultas em que
trabalho na otimizao tem um plano de execuo ruim. Ok, muitas vezes isso culpa de um ser humano
e no do otimizador, por exemplo, o DBA esqueceu de atualizar as estatsticas, ou o desenvolvedor
escreveu algum non-sarg. Mas ainda assim temos os casos onde simplesmente a culpa do otimizador,
consultas onde ele deveria gerar um plano mais eficiente.
Veja bem, eu no estou dizendo que isso um problema ou bug do SQL Server, essa uma limitao de
todos os otimizadores existentes no mercado, a quantidade de alternativas para a gerao de um plano
pode ser to grande que fica completamente impossvel pro otimizador analisar todas as opes, eu
entendo bem isso.
O otimizador de consultas do SQL Server baseado em framework chamado Cascades [2], e ele executa
uma serie de exploraes em uma consulta para tentar gerar um plano de execuo bom o suficiente
utilizando a menor quantidade de recursos possveis e, no menor tempo possvel. No SQL Server essas
exploraes so divididas em fases, e uma dessas fases conhecida como heuristic join reorder onde o
SQL tenta definir qual ser a ordem inicial de execuo dos joins. A grande dificuldade no processo de
otimizao de uma consulta fazer isso na menor tempo possvel, ou seja, preferencialmente o
otimizador nunca pode levar mais tempo para otimizar uma consulta do que ir gastar para executar o
plano. Isso pode parecer trivial, mas a quantidade de permutaes possveis para acessar uma consulta
com 12 joins seria de aproximadamente 479 milhes e considerando bushy plans teramos uma variao
de 28 trilhes, ou seja, no da pra testar todas as possibilidades para qual o melhor plano [5].
Dito isso, que fique claro que com este artigo no quero mostrar o quo ineficiente o otimizador de
consultas do SQL Server , ou o quanto ele sucks, mas quero mostrar que no mundo otimizao de
consultas, as coisas so sempre mais complicadas do que parecem .

B USHY P LANS NO SQL S ERVER


H muitos anos eu tento criar um exemplo prtico para falar sobre bushy plans (veja referencias no fim
do artigo) no SQL Server. Em poucas palavras um bushy plan uma das opes que o Otimizador tem para
poder executar os joins de sua consulta. Para efetuar uma operao de join o otimizador considera
algumas variaes de execuo de acesso as tabela e ordem de execuo dos joins, essa ordem pode
seguir um left-deep (onde o resultado do join utilizado como outer input para o prximo join) ou right-

M V T e c h | 141

SQL Server: Alm do Conceito


Blog Post Collection
deep (onde o resultado do join utilizado como inner input para o prximo join), ou um misto entre eles.
(veja a imagem abaixo para visualizar o que estou querendo dizer)
Atualmente o otimizador de consultas do SQL Server valida as opes que mencionei acima, porem existe
outra possibilidade de ordem de leituras das tabelas que no considerada por default, o bushy trees.
Bushy trees podem ser interessantes em cenrios em que o resultado de um join resulta em um filtro
considervel do resultset do join, ou seja, voc l vrias linhas, mas depois de fazer o join poucas so
retornadas. Um bushy plan (um plano com uma bushy tree) um plano que faz o join com base no
resultado de outros dois joins. Deixa eu tentar ilustrar para ver se fica mais claro:

Considerando o seguinte select:

SELECT
FROM
JOIN
JOIN
JOIN

*
A
B ON A.ID = B.ID
C ON A.ID = C.ID
D ON A.ID = D.ID

Podemos ter os seguintes planos:

A primeira rvore de joins contm um join em formato left-deep que executa os joins na seguinte ordem:
JOIN( JOIN( JOIN(A, B), C), D)
E a segunda rvore de joins contm o join em formato bushy que executa os joins na seguinte ordem:
JOIN(JOIN(A, B), JOIN(C, D))

O otimizador do SQL Server no avalia a possibilidade de bushy trees porque ela poderia gerar milhes de
possibilidades na ordem de execuo dos joins, portanto para forar a execuo de um bushy plan no SQL
M V T e c h | 142

SQL Server: Alm do Conceito


Blog Post Collection
Server temos 2 opes, usando CTEs (que eu prefiro) ou com uma sintaxe pouco convencional pra fazer
os joins, e ambas devem utilizar o hint FORCE ORDER.
Pois bem agora que voc entendeu um pouco sobre bushy plans, deixa eu te mostrar um exemplo prtico
de otimizao que podemos ter. Suponha o seguinte cenrio no banco Northwind, para criar este banco
utilize o meu script do skydrive: http://sdrv.ms/VaTL6W

Antes de comear os testes, vamos cadastrar um cliente novo e uma nova venda para este cliente:
-- Inserir venda para novo cliente
-- Cadastrar cliente "Fabiano Amorim"
INSERT INTO CustomersBig (CityID, CompanyName, ContactName, Col1,
Col2)
VALUES (57, 'Empresa do Fabiano', 'Fabiano Amorim', NEWID(),
NEWID()) -- Cidade 57 = Sao Paulo
-- Cadastrar Venda
INSERT INTO OrdersBig (CustomerID, OrderDate, Value)
VALUES(SCOPE_IDENTITY(), GetDate(), 999)
SET IDENTITY_INSERT Order_DetailsBig ON
INSERT INTO Order_DetailsBig(OrderID, ProductID, Shipped_Date,
Quantity)
VALUES (SCOPE_IDENTITY(), 1, GetDate() + 30, 999)
SET IDENTITY_INSERT Order_DetailsBig OFF
GO

Temos os seguintes ndices:


CREATE INDEX ixContactName ON CustomersBig(ContactName) -Indexando WHERE
CREATE INDEX ixProductName ON ProductsBig(ProductName) -Indexando WHERE
CREATE INDEX ixCustomerID ON OrdersBig(CustomerID) INCLUDE(Value)
-- Indexando FK
CREATE INDEX ixProductID ON Order_DetailsBig(ProductID)
INCLUDE(Quantity) -- Indexando FK
GO

E seguinte consulta:
-- Gerar "cold cache"
CHECKPOINT; DBCC FREEPROCCACHE; DBCC DROPCLEANBUFFERS;
GO
SELECT OrdersBig.OrderID,
OrdersBig.Value,
Order_DetailsBig.Quantity,
CustomersBig.ContactName,
ProductsBig.ProductName
M V T e c h | 143

SQL Server: Alm do Conceito


Blog Post Collection
FROM
INNER
ON
INNER
ON
INNER
ON
WHERE
AND
GO

OrdersBig
JOIN CustomersBig
OrdersBig.CustomerID = CustomersBig.CustomerID
JOIN Order_DetailsBig
OrdersBig.OrderID = Order_DetailsBig.OrderID
JOIN ProductsBig
Order_DetailsBig.ProductID = ProductsBig.ProductID
CustomersBig.ContactName = 'Fabiano Amorim'
ProductsBig.ProductName = 'Outback Lager 1EA81379'

Consulta tem o seguinte plano:

A performance a seguinte:

STATISTICS IO:
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0
Table 'OrdersBig'. Scan count 0, logical reads 11776, physical reads 1, read-ahead reads 11576
M V T e c h | 144

SQL Server: Alm do Conceito


Blog Post Collection
Table 'Order_DetailsBig'. Scan count 1, logical reads 10, physical reads 1, read-ahead reads 14
Table 'ProductsBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0
Table 'CustomersBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0

Temos alguns problemas com relao a este plano, o primeiro e mais interessante que por causa da
ordem que os joins sero efetuados o seek na tabela OrdersBig ser executado centenas de vezes, mais
precisamente 2344 vezes, pois esse o nmero de linhas que so retornados do join entre ProductsBig e
OrderDetails_Big. Porm sabemos que existe apenas uma order para o cliente Fabiano Amorim, ou
seja, eu esperava apenas uma operao de seek.
Como em tempo de compilao do plano o SQL Server no sabe qual o valor de CustomerID do cliente
Fabiano Amorim ele no consegue fazer a estimativa utilizando a estatstica por OrdersBig.CustomerID.
Ficou confuso? Deixa eu te mostrar com um exemplo mais simples, imagine a seguinte consulta:

SELECT
FROM
INNER
ON
WHERE

OrdersBig.OrderID, CustomersBig.ContactName
OrdersBig
JOIN CustomersBig
OrdersBig.CustomerID = CustomersBig.CustomerID
CustomersBig.ContactName = 'Fabiano Amorim'

P LANO ESTIMADO :

Repare que a estimativa de linhas que sero retornadas aps o seek pelo Fabiano Amorim de 1 linha,
porm ao consultar a tabela de OrdersBig ele estima que 1250000.00 (um milho duzentos e cinquenta)
linhas sero retornadas, crazy ha? Pois este um problema bem conhecido no mundo dos otimizadores,
M V T e c h | 145

SQL Server: Alm do Conceito


Blog Post Collection
em tempo de compilao da consulta o SQL Server no sabe qual o valor que ser retornado de
CustomersBig.Contact_ID e por isso ele no consegue estimar corretamente, dai o que ele fez? Adivinha?
Chutou que 30% da tabela ser retornada, neste caso como a tabela tem 5 milhes de linhas, ele estimou
um milho duzentos e cinquenta linhas. Multi-Column Cross-Table Statistics ajudariam e muito neste
cenrio, mas ainda no temos isso no SQL Server. Outra forma de resolver isso seria criar uma estatstica
filtrada, mas isso no vem ao caso, fica pra outro post.

UPDATE: O SQL no chutou no, ele usou a densidade para obter o valor com base na quantidade mdia
de linhas duplicadas na distribuio dos dados. Deixe-me explicar melhor.

sp_helpstats OrdersBig

Na tabela OrdersBig temos uma estatstica criada automaticamente pelo SQL Server, ou seja, ela foi criada
como uma distribuio de exemplo dos dados na tabela (WITH SAMPLE). Vamos rodar um DBCC
SHOW_STATISTICS para ver mais informaes sobre ela:

DBCC SHOW_STATISTICS(OrdersBig, _WA_Sys_00000002_5CA1C101)

Para fazer a estimativa o SQL Server usa essa informao da densidade, ele estimou o seguinte, ele faz
densidade * nmero de linhas da tabela, ou seja, 0.25 * 5000000 = 1250000, tai o valor estimado,
coincidentemente esse valor 30% da tabela o que me levou a acreditar nos 30% (my bad).
M V T e c h | 146

SQL Server: Alm do Conceito


Blog Post Collection
Na verdade a densidade da tabela de 0.2 e no 0.25, se voc atualizar a estatstica com fullscan vera que
o valor vai mudar, e consequentemente a quantidade de linhas estimadas ser de 0.2000 * 5000000, ou
seja, 100000 linhas.
Bom voltando ao plano que estamos analisando, por que o SQL Server estimou que 1.250000 linhas seriam
retornadas ele optou por no fazer o Join de CustomersBig + OrdersBig e isso est errado, sabemos que
apenas 1 linha ser retornada ele deveria ter feito o seek em CustomersBig e apenas 1 seek em OrdersBig.
O mesmo se aplica para o join entre ProductsBig e Order_DetailsBig, porm neste caso o SQL estimou
utilizando a densidade da coluna Order_DetailsBig.ProductID, dai os 2328 estimados (veja no plano
estimado da consulta completa), s pra confirmar:
-- Calculando densidade
SELECT (1.0 / COUNT(DISTINCT ProductID)) FROM Order_DetailsBig
-- Calculando estimativa com base na densidade
SELECT ROUND(0.000465549348 * 5000000, 0)

Temos:

Neste caso estimar utilizando a densidade foi excelente, pois o nmero de linhas retornadas foi de 2344,
ou seja, bem prximo do estimado que foi de 2328.
A Fabiano, mas e o Bushy plan? Calma ai, vamos l, sabendo que o Join entre CustomersBig + OrdersBig
ir retornar 1 linha, e o join entre ProductsBig + Order_DetailsBig ir retornar 2344 linhas, podemos forar
a execuo da seguinte ordem dos joins JOIN(JOIN(CustomersBig, OrdersBig), JOIN(ProductsBig,
Order_DetailsBig)), vamos testar utilizando CTEs:

-- Gerar "cold cache"


CHECKPOINT; DBCC FREEPROCCACHE; DBCC DROPCLEANBUFFERS;
GO
;WITH JoinEntre_CustomersBig_e_OrdersBig
AS
(
SELECT OrdersBig.OrderID,
OrdersBig.Value,
CustomersBig.ContactName
FROM CustomersBig
M V T e c h | 147

SQL Server: Alm do Conceito


Blog Post Collection
INNER JOIN OrdersBig
ON OrdersBig.CustomerID = CustomersBig.CustomerID
),
JoinEntre_ProductsBig_e_Order_DetailsBig
AS
(
SELECT
Order_DetailsBig.OrderID,
Order_DetailsBig.Quantity,
ProductsBig.ProductName
FROM ProductsBig
INNER JOIN Order_DetailsBig
ON Order_DetailsBig.ProductID = ProductsBig.ProductID
)
SELECT JoinEntre_CustomersBig_e_OrdersBig.OrderID,
JoinEntre_CustomersBig_e_OrdersBig.Value,
JoinEntre_ProductsBig_e_Order_DetailsBig.Quantity,
JoinEntre_CustomersBig_e_OrdersBig.ContactName,
JoinEntre_ProductsBig_e_Order_DetailsBig.ProductName
FROM JoinEntre_CustomersBig_e_OrdersBig
INNER JOIN JoinEntre_ProductsBig_e_Order_DetailsBig
ON JoinEntre_CustomersBig_e_OrdersBig.OrderID =
JoinEntre_ProductsBig_e_Order_DetailsBig.OrderID
WHERE JoinEntre_CustomersBig_e_OrdersBig.ContactName = 'Fabiano
Amorim'
AND JoinEntre_ProductsBig_e_Order_DetailsBig.ProductName =
'Outback Lager 1EA81379'
OPTION (FORCE ORDER, MAXDOP 1)
GO

Temos o seguinte plano:

M V T e c h | 148

SQL Server: Alm do Conceito


Blog Post Collection

Como voc pode observar, escrevendo as CTEs exatamente na ordem em que quero que os joins sejam
executados e utilizando o hint force order, conseguimos o plano que faz um merge join entre o resultado
dos dois joins.

A performance a seguinte:

STATISTICS IO:
Table 'Order_DetailsBig'. Scan count 1, logical reads 10, physical reads 1, read-ahead reads 14
Table 'ProductsBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0
Table 'OrdersBig'. Scan count 1, logical reads 4, physical reads 2, read-ahead reads 8
Table 'CustomersBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0

M V T e c h | 149

SQL Server: Alm do Conceito


Blog Post Collection

A diferena enorme, a consulta com o BushyPlan roda em meio segundo, isso 24 vezes mais rpido
que a query original, porm essas duas operaes de SORT (veja no plano) para fazer o Merge Join so de
assustar, SORT uma das operaes mais pesadas para fazer no banco de dados, principalmente se o
SORT for feito em disco. Para confirmar como esse sort pesado, vamos fazer um teste utilizando um
CustomerName que retorna mais Orders e outro ProductName, ou seja, mais linhas sero ordenadas.

Query original sem bushy plan:


-- Gerar "cold cache"
CHECKPOINT; DBCC FREEPROCCACHE; DBCC DROPCLEANBUFFERS;
GO
SELECT OrdersBig.OrderID,
OrdersBig.Value,
Order_DetailsBig.Quantity,
CustomersBig.ContactName,
ProductsBig.ProductName
FROM OrdersBig
INNER JOIN CustomersBig
ON OrdersBig.CustomerID = CustomersBig.CustomerID
INNER JOIN Order_DetailsBig
ON OrdersBig.OrderID = Order_DetailsBig.OrderID
INNER JOIN ProductsBig
ON Order_DetailsBig.ProductID = ProductsBig.ProductID
WHERE CustomersBig.ContactName = 'Karl Jablonski 1E663869'
AND ProductsBig.ProductName = 'Ravioli Angelo D01AFCFC'
GO

950 linhas so retornadas e a performance :

STATISTICS IO:

M V T e c h | 150

SQL Server: Alm do Conceito


Blog Post Collection
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0
Table 'OrdersBig'. Scan count 0, logical reads 11702, physical reads 1, read-ahead reads 11664
Table 'Order_DetailsBig'. Scan count 1, logical reads 9, physical reads 2, read-ahead reads 6
Table 'ProductsBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0
Table 'CustomersBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0

Query com o BushyPlan:

-- Gerar "cold cache"


CHECKPOINT; DBCC FREEPROCCACHE; DBCC DROPCLEANBUFFERS;
GO
;WITH JoinEntre_CustomersBig_e_OrdersBig
AS
(
SELECT OrdersBig.OrderID,
OrdersBig.Value,
CustomersBig.ContactName
FROM CustomersBig
INNER JOIN OrdersBig
ON OrdersBig.CustomerID = CustomersBig.CustomerID
),
JoinEntre_ProductsBig_e_Order_DetailsBig
AS
(
SELECT
Order_DetailsBig.OrderID,
Order_DetailsBig.Quantity,
ProductsBig.ProductName
FROM ProductsBig
INNER JOIN Order_DetailsBig
ON Order_DetailsBig.ProductID = ProductsBig.ProductID
)
SELECT JoinEntre_CustomersBig_e_OrdersBig.OrderID,
JoinEntre_CustomersBig_e_OrdersBig.Value,
JoinEntre_ProductsBig_e_Order_DetailsBig.Quantity,
JoinEntre_CustomersBig_e_OrdersBig.ContactName,
JoinEntre_ProductsBig_e_Order_DetailsBig.ProductName
FROM JoinEntre_CustomersBig_e_OrdersBig
INNER JOIN JoinEntre_ProductsBig_e_Order_DetailsBig
ON JoinEntre_CustomersBig_e_OrdersBig.OrderID =
JoinEntre_ProductsBig_e_Order_DetailsBig.OrderID
WHERE JoinEntre_CustomersBig_e_OrdersBig.ContactName = 'Karl
Jablonski 1E663869'
AND JoinEntre_ProductsBig_e_Order_DetailsBig.ProductName =
'Ravioli Angelo D01AFCFC'
OPTION (FORCE ORDER, MAXDOP 1)
M V T e c h | 151

SQL Server: Alm do Conceito


Blog Post Collection
GO

950 linhas so retornadas e a performance :

STATISTICS IO:
Table 'Order_DetailsBig'. Scan count 1, logical reads 9, physical reads 2, read-ahead reads 6, lob logical
reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'ProductsBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0, lob logical reads
0, lob physical reads 0, lob read-ahead reads 0.
Table 'OrdersBig'. Scan count 1, logical reads 5720, physical reads 4, read-ahead reads 5728, lob logical
reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'CustomersBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0, lob logical reads
0, lob physical reads 0, lob read-ahead reads 0.

Ainda que o nmero de reads seja menor, o tempo foi de 13 segundos, contra 7 do plano sem bushy plan,
tambm podemos perceber que existe um sort warning no profiler, ou seja, a operao de sort foi escrita
em disco, provavelmente esse foi o motivo da performance ser to ruim, o que podemos tentar fazer
evitar esse SORT, como? Forando o JOIN entre os resultados ser executado utilizando o algoritmo de
HASH JOIN, vejamos a diferena:
-- Gerar "cold cache"
CHECKPOINT; DBCC FREEPROCCACHE; DBCC DROPCLEANBUFFERS;
GO
;WITH JoinEntre_CustomersBig_e_OrdersBig
AS
(
SELECT OrdersBig.OrderID,
OrdersBig.Value,
CustomersBig.ContactName,
CustomersBig.CityID
FROM CustomersBig
INNER JOIN OrdersBig
M V T e c h | 152

SQL Server: Alm do Conceito


Blog Post Collection
ON OrdersBig.CustomerID = CustomersBig.CustomerID
),
JoinEntre_ProductsBig_e_Order_DetailsBig
AS
(
SELECT
Order_DetailsBig.OrderID,
Order_DetailsBig.Quantity,
ProductsBig.ProductName
FROM ProductsBig
INNER JOIN Order_DetailsBig
ON Order_DetailsBig.ProductID = ProductsBig.ProductID
)
SELECT JoinEntre_CustomersBig_e_OrdersBig.OrderID,
JoinEntre_CustomersBig_e_OrdersBig.Value,
JoinEntre_ProductsBig_e_Order_DetailsBig.Quantity,
JoinEntre_CustomersBig_e_OrdersBig.ContactName,
JoinEntre_ProductsBig_e_Order_DetailsBig.ProductName
FROM JoinEntre_CustomersBig_e_OrdersBig
INNER HASH JOIN JoinEntre_ProductsBig_e_Order_DetailsBig
ON JoinEntre_CustomersBig_e_OrdersBig.OrderID =
JoinEntre_ProductsBig_e_Order_DetailsBig.OrderID
WHERE JoinEntre_CustomersBig_e_OrdersBig.ContactName = 'Karl
Jablonski 1E663869'
AND JoinEntre_ProductsBig_e_Order_DetailsBig.ProductName =
'Ravioli Angelo D01AFCFC'
OPTION (FORCE ORDER, MAXDOP 1)
GO

Vejamos a performance:

STATISTICS IO:
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0
Table 'Order_DetailsBig'. Scan count 1, logical reads 9, physical reads 2, read-ahead reads 6
Table 'ProductsBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0
M V T e c h | 153

SQL Server: Alm do Conceito


Blog Post Collection
Table 'OrdersBig'. Scan count 1, logical reads 5720, physical reads 4, read-ahead reads 5728
Table 'CustomersBig'. Scan count 1, logical reads 3, physical reads 3, read-ahead reads 0

Repare que ainda que tenhamos a presena de um Hash Warning indicando que parte da operao de
hash utilizou tempdb (disco) ainda assim temos performance melhor que a consulta sem bushy join, neste
caso o tempo foi de de 4 segundos.
O que precisamos ter em mente o seguinte, quanto menos linhas forem retornadas dos joins, melhor
ser a performance do bushy plan, se voc por exemplo utilizar um filtro de cliente ou produto que no
existe ter uma performance sensacional.

CONCLUSO

N OTA IMPORTANTE :
A demonstrao acima meramente ilustrativa, eu no estou dizendo pra voc sair utilizando FORCE
ORCER ou qualquer outro hint em todas as consultas do seu ambiente, meu objetivo te apresentar a
funcionalidade e dizer para usar com conscincia, se no entendeu, no use, o efeito do mal uso dessa
tcnica ou do uso de qualquer outro hint pode ser desastroso, portanto cuidado.
Bom isso pessoal, o mundo otimizao de consultas enorme e muitas vezes consistem no processo de
tentativa e erro, porm conhecer bem as alternativas existentes e como o otimizador de consultas
funciona, nos ajuda a minimizar este processo rduo de tentar otimizar um plano.
Espero que voc tenha chegado at aqui e gostado do artigo, trabalhei com conceitos importantes do
otimizador de consultas e saiba que nem sempre o resultado real o que foi estimado.
Thats all folks.

REFERNCIAS:
ACM Paper: Left-deep vs. bushy trees: an analysis of strategy spaces and its implications for query
optimization
G. Graefe. The Cascades framework for query optimization. Data Engineering Bulletin, 18(3), 1995.
Microsoft Research: Polynomial Heuristics for Query Optimization
Itzik Ben-Gan: T-SQL Deep Dives: Create Efficient Queries
Benjamin Nevarez: Optimizing Join Orders
Wikipedia: http://en.wikipedia.org/wiki/Query_optimizer
M V T e c h | 154

SQL Server: Alm do Conceito


Blog Post Collection

Sulamita Dantas
www.sulamitadantas.com.br

Policy Based Management


O PBM (Policy Based Management - Gerenciamento Baseado em Poltica) passou a ser utilizado a partir
da verso do SQL Server 2008, permitindo uma padronizao das instncias, uma vez que nas verses
anteriores, a mesma tinha que ser feita manualmente, ou seja, o BPM permite ao DBA ter o controle do
seu ambiente, aplicando as melhores prticas de organizao e segurana, tornando mais fcil o seu
processo de manuteno.
Quando o servidor possui poucas instncias, tudo bem, d para o DBA administrar manualmente, mas e
quando so vrios servidores e muitas instncias em cada um deles? J imaginou o trabalho que o DBA
tem para ter o controle?
Exemplo: se o DBA precisava criar uma rotina com as melhores prticas para saber quais bancos estavam
com o AutoShrink e AutoClose desabilitados, ele tinha quer ir manualmente, e olhar banco por banco nas
instncias, ou criar scripts enormes para fazer tal verificao.
Atravs do PBM possvel verificar de imediato quais bancos em uma instncia esto com o AutoShrink
e AutoClose desabilitados.

De acordo com Mike Hotek1, O BPM possui alguns conceitos bsicos:


Facet - So o objeto bsico sobre o qual os padres so estabelecidos. Definem o tipo de objeto ou opo
a ser verificada, como banco de dados por exemplo.
Condition - So equivalentes a uma clusula WHERE, que define os critrios que precisam ser verificados.
Policy - a unio da Facet com a Condition
On Change: Prevent - Cria Triggers DDL, para impedir uma alterao que viole a diretiva.
On Change: Log Only - Verifica a diretiva automaticamente quando feita uma alterao usando a
infraestrutura de notificao de evento.
On Schedule - Cria uma tarefa do SQL Server Agent para verificar a diretiva em um horrio definido.
On Demand - Avalia a diretiva quando executada diretamente por um usurio.

1 Hotek, Mike. Kit de treinamento MCTS(Exame 70-432): Microsoft SQL SERVER 2008: Implementao e
manuteno/ Mike Hotek.

M V T e c h | 155

SQL Server: Alm do Conceito


Blog Post Collection

Aps entender os conceitos acima, segue abaixo o exemplo: implementar uma poltica de melhores
prticas para um banco ou vrios bancos(AutoShrink e AutoClose desabilitados):
- Abrir Management Studio
- Ao Expandir a aba Management, clique em cima de Condition com o boto direito do mouse, selecione
new condition:

Nos campos abaixo:


Name: coloque o nome da politica
Facet: escolha uma das facetas que deseja usar para criar a poltica(nesse caso, ser a Database).
Expression: nesse campo crie a expresso de acordo com condio desejada.

M V T e c h | 156

SQL Server: Alm do Conceito


Blog Post Collection

Aps clicar em ok, j pode verificar que a condio foi criada.

Agora prximo passo criar a policie:

clique com o boto direito do mouse em cima de policie, selecione new policie

M V T e c h | 157

SQL Server: Alm do Conceito


Blog Post Collection

Nos campos abaixo:

M V T e c h | 158

SQL Server: Alm do Conceito


Blog Post Collection
Name: coloque o nome da policie
Check Condition: clique na seta e ache a condio que foi criada.
Against Targets: Selecione Every Database
Evaluation Mode: On Demand

Aps clicar em ok, verifique a policie criada

Verificando a poltica das melhores prticas:

Clicar com o boto do mouse direito em cima da policie criada


Selecionar Evaluate

M V T e c h | 159

SQL Server: Alm do Conceito


Blog Post Collection

Clique na opo view

M V T e c h | 160

SQL Server: Alm do Conceito


Blog Post Collection

Existem vrias opes das facets, basta escolher qual deseja e criar!

M V T e c h | 161

SQL Server: Alm do Conceito


Blog Post Collection

Marcelo Fernandes
marcelodba.wordpress.com

Solucionando Problemas: Error Failed to open loopback connection ao


executar SP_READERRORLOG
INTRODUO

Tenho um ambiente com SQL Server 2008 instalado em um Windows Server 2008 R2 Service Pack 1 em
Cluster, ao executar ao procedure SP_READERRORLOG exibida uma mensagem de erro Failed to open
loopback connection.

S INTOMA
Ao executar a SP_READERRORLOG o seguinte erro ocorre:
Msg 22004, Level 16, State 1, Line 0
Failed to open loopback connection. Please see event log for more information.
Msg 22004, Level 16, State 1, Line 0
error log location not found

C AUSA
Ao executar o SP_READERRORLOG o SQL Server abre uma conexo com o prprio servidor (loopback) e
neste momento o erro ocorria, para identificar o erro iniciei o ProcessMonitor que pode ser baixado no
site da Microsoft, e ao executar o sp_readerrorlog juntamente com o ProcessMonitor notei o erro abaixo
no ProcessMonitor.

M V T e c h | 162

SQL Server: Alm do Conceito


Blog Post Collection

Observando minha estrutura de cluster, o SQL Server est tentando abrir uma conexo com o nome do
meu recurso de MSDTC.

Sabemos que o SP_READERRORLOG faz uma conexo no loopback, mas por algum motivo recebi uma
tentativa de conexo no nome do recurso de MSDTC (MSDTCP12) do meu cluster, ao observar as
dependncias do servio do SQL observei que o servio SQL dependia do nome MSDTCP12.

S OLUO
M V T e c h | 163

SQL Server: Alm do Conceito


Blog Post Collection
Remova a dependncia de qualquer recurso name que no seja o nome de sua instncia SQL (no meu
caso o nome do DTC)

L EITURAS ADICIONAIS
O Fabricio Catae tem um artigo com o mesmo erro, mas com origens
distintas
http://blogs.msdn.com/b/fcatae/archive/2010/03/03/problema-the-system-detected-apossible-attempt-to-compromise-security-parte-1.aspx

M V T e c h | 164

SQL Server: Alm do Conceito


Blog Post Collection

Error to install SQL Server 2008 on Windows 2012


Hello Friends
This week I faced an interesting error My PFE friend Alex Rosa (blog) helped me to fix this problem and
Im sharing this problem / solution because it might help you.
The environment and Goal
A Windows 2012 R2 on cluster with 2 nodes and my goal was to setup a SQL Server 2008 in cluster.
The problem
Firstly, I must say that since Jul/14 SQL 2K8 is no longer supported, SQL2K8 is in Extended Support.
When SQL Server 2008 was released there wasnt Windows 2012, so SQL Server was made based on
Windows 2k8, Im not saying that SQL 2k8 is not supported on Windows 2012, SQL is supported on
Windows 2012. but some functionality were made based on Win2K8.

During the installation of SQL2K8 on Win12 on the first node I faced this error message:

M V T e c h | 165

SQL Server: Alm do Conceito


Blog Post Collection

I do have my Cluster on online status and working well and I ran the cluster validation successfully, but
during the SQL setup I faced a message error saying that my setup couldnt check my cluster service,
bellow we have part of the detail of the Report Setup Validation:
InstallFailoverClusterGlobalRules: SQL Server 2008 Setup configuration checks for rules group
InstallFailoverClusterGlobalRules
SQLNOD
E1

Cluster_IsOnline

Verifies
that the
cluster
service is
online.

M V T e c h | 166

Faile
d

The
SQL
Server
failover
cluster
services is
not online,
or
the
cluster
cannot be
accessed
from one
of
its

SQL Server: Alm do Conceito


Blog Post Collection
nodes. To
continue,
determine
why
the
cluster is
not online
and rerun
Setup. Do
not rerun
the
rule
because
the
rule
cannot
detect
a
cluster
environme
nt.
SQLNOD
E1

Cluster_SharedDiskF
acet

Checks
whether
the
cluster
on
a
compute
r has at
least one
shared
disk
available
.

Faile
d

The cluster
on
this
computer
does not
have
a
shared disk
available.
To
continue,
at
least
one shared
disk must
be
available.

SQLNOD
E1

Cluster_VerifyForErr
ors

Checks if
the
cluster
has been
verified
and
if
there are
any
errors or

Faile
d

The cluster
either has
not been
verified or
there are
errors or
failures in
the
verification

M V T e c h | 167

SQL Server: Alm do Conceito


Blog Post Collection
failures
reported
in
the
verificati
on
report.

report.
Refer
to
KB953748
or
SQL
Server
Books
Online for
more
informatio
n.

I also tried running the setup from the command line using the SKIP_RULES:
Setup /SkipRules=Cluster_VerifyForErrors /Action=InstallFailoverCluster
And I got the same error
Looking at the detail of the first error, the message says that the SQL couldnt verify the cluster service,
the cluster was online but setup couldnt access my cluster.
I did some research on the web and I found this article:
http://blogs.msdn.com/b/clustering/archive/2012/04/06/10291601.aspx
The author (Rob-MSFT) gave me a clue:
These are deprecated features (Failover Cluster Command Interface (cluster.exe)
and Failover Cluster Automation Server) in Windows Server 2012 but are made
available, as there are still some applications that may need them, SQL Server being
one of them. Installing it may be necessary for any legacy scripts you have built on
the old Cluster.exe command line interface.

During the SQL Server 2008 installations the setup tries to check cluster service using a deprecated
feature!
Checking my cluster installations using the articles from Rob I have this:

Get-WindowsFeature RSAT-Cluster*

M V T e c h | 168

SQL Server: Alm do Conceito


Blog Post Collection

These is the features installed by default when we install the Cluster Feature.
The Solution
We just need to enable the Failover Cluster Automation Server, to achieve this you just need to run the
PowerShell command bellow.

Install-WindowsFeature -Name RSAT-Clustering-AutomationServer

After these steps well have success on our setup:

M V T e c h | 169

SQL Server: Alm do Conceito


Blog Post Collection

PS: You need to run these steps on all Cluster nodes.

Regards.

M V T e c h | 170

SQL Server: Alm do Conceito


Blog Post Collection

Token Bloat - Cannot generate SSPI context


Ol amigos, h um tempo atrs enfrente o famoso problema SSPI atpico e sempre adiava este post, bom
finalmente tomei decidi escrever o artigo.

P ROBLEMA
Um usurio sempre conectou ao SQL Server sem problemas, mas um dia ao tentar conectar-se ao mesmo
servio de SQL ele recebeu a seguinte mensagem:

No houve nenhuma mudana por parte de infraestrutura e DBAs no servidor, o usurio simplesmente
no consegue conectar mais, e o mais intrigante que outros usurios conseguem conectar-se e alguns
no.
Bom, na grande maioria das vezes o erro SSPI Context gerado por falta de SPN em uma tentativa de
conexo via kerberos com o SQL Server e para resolver este problema basta criar o SPN.
Listando os SPN atuais:
No prompt de comando digite o seguinte comando
M V T e c h | 171

SQL Server: Alm do Conceito


Blog Post Collection
SETSPN L <domnio\conta_de_servio_do_SQL>

Nota: Se ao executar o comando setspn L voc no receber o SPN para a sua instncia de SQL Server,
voc deve criar o SPN e voc est recebendo o erro de SSPI Context, possivelmente o seu problema ser
resolvido com a criao manual do SPN com o seguinte comando:
SETSPN A MSSQLSvc/fqdn <domnio>\<conta de servio do SQL>
SETSPN A MSSQLSvc/fqdn:1433 <domnio>\<conta de servio do SQL>
Ex. SETSPN A MSSLSvc/sqlproducao.contoso.com contoso\sqlServiceAcc

Maiores informaes no artigo: https://msdn.microsoft.com/pt-br/library/ms191153.aspx

Como podemos observar no resultado do SETSPN L no meu ambiente eu tenho os SPNs corretamente
criados!
O que justifica algumas conexes conseguirem conectar-se, pois o SPN est ok, e ento por que algumas
conexes recebem o SSPI?
Para responder esta questo precisamos analisar o ticket do kerberos, executando a ferramenta tokensz
voc poder evidenciar o problema de token bloat com a seguinte sintaxe
tokensz.exe /compute_tokensize /user:<usurio_com_erro_sspi>

M V T e c h | 172

SQL Server: Alm do Conceito


Blog Post Collection

Como podemos notar na imagem acima, o tamanho mximo do Token 12000 (12K) e o token do usurio
contoso\usuarioSQL que estou tentando conectar-se ao SQL e estou recebendo o erro SSPI contexto
ultrapassou o limite me 67 Bytes
Um token basicamente contm os grupos e permisses de um usurio e criado no momento do logon e
este token repassado aos outros servios/servidores conforme o usurio necessita autenticar-se para
consumir os servios (para maiores detalhes sobre kerberos consulte o artigo
https://msdn.microsoft.com/en-us/library/bb742516.aspx)

Pois bem, se em um token temos a ACL (Access control List) vamos investigar os usurios criados:

M V T e c h | 173

SQL Server: Alm do Conceito


Blog Post Collection

Os dois usurios so membros do grupo SQLacesso o qual foi criado o login no SQL Server, mas o segundo
usurio membro de mais algumas centenas de grupos.
At o Windows 2008 R2 o tamanho mximo default de um token de 12K a partir do Windows 2012 este
valor foi alterado para 48K
Dependendo do tamanho de seu ambiente este limite de 12K facilmente alcanado com um usurio
pertencendo a aproximadamente 150 grupos.
Em uma empresa multinacional onde como boa prtica so criados diversos grupos para controlar acessos
a diversos compartilhamentos, servidores, aplicaes etc. este limite alcanado muito rapidamente.

Qual o tamanho de cada grupo?


Para calcular o tamanho do token utilizamos a seguinte formula:
TokenSize = 1200 + 40d + 8s
Onde:
D = (grupos domnio local + grupos universais externos)
S = (grupos globais + Universal)

Existem diversos scripts que automatizam este clculo, abaixo um bem simples que encontrei no artigo
http://www.cluberti.com/blog/2014/05/26/getting-kerberos-token-size-with-powershell/
# Always credit where due - this was found via
# http://jacob.ludriks.com/getting-kerberos-token-size-with-powershell/
M V T e c h | 174

SQL Server: Alm do Conceito


Blog Post Collection

#Gets max token size


#Run with .\get_tokensize.ps1 -Username "domain\username"
#Reference: http://support.microsoft.com/kb/327825
#tokensize = 1200 + 40d + 8s
Param(
[Parameter(Mandatory=$True)]
[String]$Username
)
$domain = ($username.split("\"))[0]
$user = ($username.split("\"))[1]
Import-Module ActiveDirectory
$rootdse = (Get-ADDomain $domain).distinguishedname
$server = (Get-ADDomain $domain).pdcemulator
$usergroups
=
Get-ADPrincipalGroupMembership
distinguishedname,groupcategory,groupscope,name

-server

$server

$user

select

$domainlocal = [int]@($usergroups | where {$_.groupscope -eq "DomainLocal"}).count


$global = [int]@($usergroups | where {$_.groupscope -eq "Global"}).count
$universaloutside = [int]@($usergroups | where {$_.distinguishedname -notlike "*$rootdse" -and
$_.groupscope -eq "Universal"}).count
$universalinside = [int]@($usergroups | where {$_.distinguishedname -like "*$rootdse" -and
$_.groupscope -eq "Universal"}).count
$tokensize = 1200 + (40 * ($domainlocal + $universaloutside)) + (8 * ($global + $universalinside))
Write-Host "
Domain local groups: $domainlocal
Global groups: $global
Universal groups outside the domain: $universaloutside
Universal groups inside the domain: $universalinside
Kerberos token size: $tokensize"
M V T e c h | 175

SQL Server: Alm do Conceito


Blog Post Collection
Outros scripts teis
http://www.jhouseconsulting.com/2013/12/20/script-to-create-a-kerberos-token-size-report-1041
https://gallery.technet.microsoft.com/scriptcenter/Check-for-MaxTokenSize-520e51e5

C OMO R ESOLVER

Voc tem duas maneiras de resolver o problema, aumentando o default do token size ou excluindo grupos
desnecessrios.
Para aumentar o token size, voc pode seguir as etapas do KB http://support.microsoft.com/kb/938118
E M CADA ESTAO :
Inicie Regedt32.exe
Localize a chave (HKLM\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters)
No menu Edit clique em NEW / DWORD e utilize os parmetros abaixo:
Nome: MaxTokenSize
tipo: REG_DWORD
Base: Decimal
Valor: 48000

Feche o Editor de Registro


Se executarmos novamente a ferramenta Tokensz teremos o seguinte resultado:

M V T e c h | 176

SQL Server: Alm do Conceito


Blog Post Collection

LEITURAS ADICIONAIS

http://support.microsoft.com/kb/938118
http://blogs.technet.com/b/shanecothran/archive/2010/07/16/maxtokensize-and-kerberos-tokenbloat.aspx
http://support.microsoft.com/kb/327825/en-us
http://blogs.technet.com/b/askds/archive/2012/07/27/kerberos-errors-in-network-captures.aspx
http://blogs.technet.com/b/askds/archive/2007/11/02/what-s-in-a-token.aspx
http://support.microsoft.com/kb/327825/en-us
http://blogs.technet.com/b/askds/archive/2012/09/12/maxtokensize-and-windows-8-and-windowsserver-2012.aspx

M V T e c h | 177

SQL Server: Alm do Conceito


Blog Post Collection

Cibelle Castro
cibellecastro.wordpress.com

Auditoria
Descobrindo Auditoria no SQL Server 2008

Abordaremos neste artigo a auditoria em banco de dados, no entanto, antes de falarmos sobre isso, pense
no que a palavra auditoria quer dizer para voc. Onde voc ouviu falar a primeira vez nessa palavra? Mas
porque todas essas perguntas? O objetivo delas demonstrar que independente da rea que a auditoria
seja implementada, todas desejam um mecanismo para ajudar a descobrir algo sobre algum, alguma
coisa, alguma ao, nos mostrar que tentaram entrar no sistema, enfim dar segurana aos nossos dados.
Qual DBA nunca se deparou com a seguinte situao: Ahhhhhh algum tirou as minhas permisses! ou
Quero saber quem alterou a stored procedure que eu fiz, semana passada ela estava funcionando, ou
qualquer relao que necessitamos rastrear as alteraes que foram feitas nos dados. Quem fez, quando
fez e o que foi modificado? Dependendo da empresa, ser primordial ter uma auditoria implementada,
seja ela exigida pelo ramo do negcio ou por determinao da lei.
Antes do SQL Server 2008, era necessrio utilizar diversos recursos para fazer todo o conjunto de auditoria
para uma instncia. Usvamos as triggers DDL como o prprio nome diz faziam a auditoria de alteraes
DDL, as triggers DML faziam a auditoria dos dados modificados em tabelas ou views, tinha a opo de usar
o SQL Trace fazia a auditoria de instrues SELECT ou ainda algumas ferramentas de terceiros.
O SQL Server 2008 possui uma ferramenta excelente, o SQL Server Audit combina todos os recursos de
auditoria.

P OR QUE UTILIZAR AUDI TORIA ?


Voc poderia estar se perguntando: quais as vantagens de implementar auditoria do SQL Server no meu
ambiente? SQL Server Audit possui vrias caractersticas e benefcios, dentre elas:
Auditoria em nvel de instncia e banco de dados;
Auditoria de atividades;
Capacidade de capturar e exibir os resultados da auditoria;
Alta granularidade;
Leve e rpido;
Facilidade de configurar e administrar;
Mais complexo e mais fcil que utilizar triggers;
M V T e c h | 178

SQL Server: Alm do Conceito


Blog Post Collection
Facilidades atravs do SSMS;
P ODE SER FEITO ATRAVS DE S CRIPTS .
N OTA 01:
O SQL Server Audit utiliza Extended Events Engine para capturar os dados da auditoria. Isso resulta em
um rpido desempenho e sobrecarga mnima em comparao ao uso de SQL Trace para capturar esse
tipo de atividade.

C OMO O SQL S ERVER A UDIT TRABALHA ?


Nesta seo, vamos ver uma viso geral de como funciona o SQL Server Audit. O fluxograma mostrado na
Figura 1 deve fornecer uma viso ampla do que est envolvido na criao de auditoria.

Figura 01. Fluxograma que mostra como criar uma nova auditoria de servidor SQL

A auditoria do SQL Server permite que voc crie vrias auditorias diferentes, atendendo a maior parte
todas das atividades que ocorre dentro do SQL Server.
Existem quatro principais objetos para se configurar a auditoria, Server Audit Object, Target, Server Audit
Specification e o Database Audit Specification, vamos detalhar um pouco mais sobre cada item:
O primeiro passo ao criar uma nova auditoria em uma instncia do SQL Server 2008 criar um SQL Server
Audit Object, que responsvel por coletar e agrupar as aes que sero monitoradas.

M V T e c h | 179

SQL Server: Alm do Conceito


Blog Post Collection
Quando voc cria um SQL Server Audit Object, deve-se atribuir um nome, selecionar as opes de
configurao, e dizer qual o TARGET.
O TARGET o local onde os dados de auditoria sero armazenados que pode ser um arquivo no disco
(audit file), o log de aplicaes do Windows (Application EVENT LOG) ou no log de segurana do Windows
(Security EVENT LOG). Se a forma de armazenamento escolhida for audit file, voc poder escolher a
pasta onde esses arquivos sero gerados e poder especificar o tamanho mximo de um arquivo. Alm
disso, possvel alocar previamente espao em disco para o log de auditoria, em vez de fazer o arquivo
crescer medida que as linhas de auditoria so adicionadas.

Quando o Application ou o Security Log so especificados, as nicas opes disponveis para configurao
so:
Queue Delay: quantidade de tempo em milissegundos que os eventos so armazenados antes de serem
armazenados. Para permitir que a entrega de eventos seja sncrona, voc deve preencher esse campo
com 0 (QUEUE_DELAY = 0). O valor default 1000, o que equivale a 1 segundo. Se especificar um
tempo de atraso, os registros de auditoria podero ser acumulados, mas mesmo assim devero ser
gravados dentro do intervalo especificado;
Shutdown on Failure: A ao ON_FAILURE controla como a instncia se comporta se os registros de
auditoria no podem ser gravados. A opo default CONTINUE, a qual permite que a instncia continue
a execuo e processe as transaes. Caso voc altere o valor para SHUTDOWN, a instncia ser encerrada
se os eventos de auditoria no puderem ser escritos no target.

Sintaxe Server Audit:

CREATE SERVER AUDIT audit_name


{
TO { [ FILE (<file_options> [ , ...n ]) ] | APPLICATION_LOG |
SECURITY_LOG }
[ WITH ( <audit_options> [ , ...n ] ) ]
}
[ ; ]
<file_options>::=
{
FILEPATH = 'os_file_path'
[ , MAXSIZE = { max_size { MB | GB | TB } | UNLIMITED } ]
[ , MAX_ROLLOVER_FILES = { integer | UNLIMITED } ]
[ , RESERVE_DISK_SPACE = { ON | OFF } ]
}
<audit_options>::=
{
[ QUEUE_DELAY = integer ]
[ , ON_FAILURE = { CONTINUE | SHUTDOWN } ]
M V T e c h | 180

SQL Server: Alm do Conceito


Blog Post Collection
[ , AUDIT_GUID = uniqueidentifier ]
}

Se voc prestar ateno na sintaxe, perceber que pode ser facilmente configurado.
N OTA 02:

No possvel escrever no log de segurana no Windows XP;


Um objeto de auditoria sempre inicia desabilitado;
O log de segurana pode ser integrado com o ACS (AUDIT COLLECTION SERVICES) do System Center
Operations Manager 2007;
Qualquer usurio autenticado pode ler/escrever no log de aplicaes do Windows. Este log requer menos
permisses e menos seguro que o log de segurana do Windows.

O segundo passo criar o que chamado de Audit Specification. A auditoria do SQL Server oferece dois
tipos diferentes de especificaes de auditoria:
SERVER AUDIT SPECIFICATIONS;
DATABASE AUDIT SPECIFICATIONS;
Server e Database Audit Specification so criados de forma diferente. Vamos conhecer um pouco mais o
conceito de cada um desses tipos.
SERVER AUDIT SPECIFICATIONS
Define os grupos de aes (action groups) que ocorrem no nvel de instncia do SQL Server e os agrupa
em audit action groups. Por exemplo, podem ser usados quando voc deseja auditar uma atividade, tais
como login, logout, alteraes de senhas, quando um comando de backup ou restore disparada dentre
outas coisas .
Existe um relacionamento um-para-um entre o Server Audit Specification Object e o Server Audit Object.
A regra simples um SQL Server Audit Object s pode ser associado com um Audit Specification porque
ambos so criados no escopo da instncia do SQL Server.
As aes auditadas so enviadas para o SQL Server Audit que grava essas aes no TARGET. Na tabela 01
esto descritos os audit actions groups.

Action Group Name

M V T e c h | 181

SQL Server: Alm do Conceito


Blog Post Collection
APPLICATION_ROLE_CHANGE_PASSWORD_GROUP
AUDIT_CHANGE_GROUP
BACKUP_RESTORE_GROUP
BROKER_LOGIN_GROUP
DATABASE_CHANGE_GROUP
DATABASE_MIRRORING_LOGIN_GROUP
DATABASE_OBJECT_ACCESS_GROUP
DATABASE_OBJECT_CHANGE_GROUP
DATABASE_OBJECT_OWNERSHIP_CHANGE_GROUP
DATABASE_OBJECT_PERMISSION_CHANGE_GROUP
DATABASE_OPERATION_GROUP
DATABASE_OWNERSHIP_CHANGE_GROUP
DATABASE_PERMISSION_CHANGE_GROUP
DATABASE_PRINCIPAL_CHANGE_GROUP
DATABASE_PRINCIPAL_IMPERSONATION_GROUP
DATABASE_ROLE_MEMBER_CHANGE_GROUP
DBCC_GROUP
FAILED_LOGIN_GROUP
FULLTEXT_GROUP
LOGIN_CHANGE_PASSWORD_GROUP
LOGOUT_GROUP
SCHEMA_OBJECT_ACCESS_GROUP
SCHEMA_OBJECT_CHANGE_GROUP
SCHEMA_OBJECT_OWNERSHIP_CHANGE_GROUP
SCHEMA_OBJECT_PERMISSION_CHANGE_GROUP
SERVER_OBJECT_CHANGE_GROUP
SERVER_OBJECT_OWNERSHIP_CHANGE_GROUP

M V T e c h | 182

SQL Server: Alm do Conceito


Blog Post Collection
SERVER_OBJECT_PERMISSION_CHANGE_GROUP
SERVER_OPERATION_GROUP
SERVER_PERMISSION_CHANGE_GROUP
SERVER_PRINCIPAL_CHANGE_GROUP
SERVER_PRINCIPAL_IMPERSONATION_GROUP
SERVER_ROLE_MEMBER_CHANGE_GROUP
SERVER_STATE_CHANGE_GROUP
SUCCESSFUL_LOGIN_GROUP
TRACE_CHANGE_GROUP
Tabela 01 Audit Action Groups. Fonte: http://technet.microsoft.com/en-us/library/cc280663.aspx

Podemos obter o resultado da Tabela 01 fazendo uma consulta na DMV sys.dm_audit_actions.

SELECT
--Action_in_log -> Indica se uma ao pode ser gravada em
um log de auditoria. Os valores so os seguintes: 1 = Sim e 0 =
No
Action_in_log,
--Name -> Nome da ao de auditoria ou do grupo de aes de
auditoria. No pode ser nulo.
Name
FROM
Sys.dm_audit_actions
WHERE
-- Class_desc -> O nome da classe do objeto ao qual a ao
de auditoria aplica-se
Class_desc ='SERVER'
-- Configuration_level ->Indica que a ao ou o grupo de
aes especificado nessa linha so configurveis no nvel do
Grupo ou da Ao
AND Configuration_level ='Group'
ORDER BY
Name

Ao criar qualquer tipo de Audit Specification (Nota 02), voc primeiro atribuir-lhe um nome e associa o
Audit Specification com o SQL Server Audit Object criado na primeira etapa. O ltimo passo para criao
de uma especificao de auditoria de servidor atribuir-lhe um Audit Action type que nada mais do que
uma atividade pr-definida que acontece dentro do SQL Server e podem ser auditadas.
M V T e c h | 183

SQL Server: Alm do Conceito


Blog Post Collection
N OTA 03:
Sintaxe para criar um Server Audit Specification por T-SQL:
CREATE SERVER AUDIT SPECIFICATION audit_specification_name
FOR SERVER AUDIT audit_name
{
{ ADD ( { audit_action_group_name } )
} [, ...n]
[ WITH ( STATE = { ON | OFF } ) ]
}
[ ; ]

DATABASE AUDIT SPECIFICATIONS


Usado quando voc deseja auditar uma atividade dentro de um banco de dados, como quem est
selecionando dados de uma tabela particular.
A regra a cada Database Audit Specification pode ser associado a apenas um Server Audit Object.
Entretanto um Server Audit Object pode ser associado a apenas um Database Audit Specification por
banco de dados. Ou seja, voc pode criar mltiplos Database Audit Speficications por banco de dados
desde que cada um use um Server Audit Object separado. Veja Figura 02.

M V T e c h | 184

SQL Server: Alm do Conceito


Blog Post Collection
Figura 02. Descrio geral de auditoria.

No nvel de instncia, voc pode especificar um ou mais Audit Action Group (para Database Audit
Specification voc pode especificar aes de auditoria individual e filtros tambm).
Na tabela 02 esto descritos as aes ou grupos de ao que podem ser configurados.
Action Name

Action Group Name

DELETE

APPLICATION_ROLE_CHANGE_PASSWORD_GROUP

EXECUTE

AUDIT_CHANGE_GROUP

INSERT

BACKUP_RESTORE_GROUP

RECEIVE

DATABASE_CHANGE_GROUP

REFERENCES

DATABASE_OBJECT_ACCESS_GROUP

SELECT

DATABASE_OBJECT_CHANGE_GROUP

UPDATE

DATABASE_OBJECT_OWNERSHIP_CHANGE_GROUP
DATABASE_OBJECT_PERMISSION_CHANGE_GROUP
DATABASE_OPERATION_GROUP
DATABASE_OWNERSHIP_CHANGE_GROUP
DATABASE_PERMISSION_CHANGE_GROUP
DATABASE_PRINCIPAL_CHANGE_GROUP
DATABASE_PRINCIPAL_IMPERSONATION_GROUP
DATABASE_ROLE_MEMBER_CHANGE_GROUP
DBCC_GROUP
SCHEMA_OBJECT_ACCESS_GROUP
SCHEMA_OBJECT_CHANGE_GROUP
SCHEMA_OBJECT_OWNERSHIP_CHANGE_GROUP
SCHEMA_OBJECT_PERMISSION_CHANGE_GROUP

Tabela 02. Fonte: http://technet.microsoft.com/en-us/library/cc280663.aspx

M V T e c h | 185

SQL Server: Alm do Conceito


Blog Post Collection
Neste objeto podemos coletar dados como DELETE, INSERT, SELECT, UPDATE, EXECUTE, DBCC_GROUP
etc. Para visualizarmos todos os objetos descritos na Tabela 02, basta fazermos uma pesquisa na DMV
sys.dm_audit_actions.

SELECT
--Action_in_log -> Indica se uma ao pode ser gravada em
um log de auditoria. Os valores so os seguintes: 1 = Sim e 0 =
No
Action_in_log,
--Name -> Nome da ao de auditoria ou do grupo de aes de
auditoria. No pode ser nulo.
Name
FROM
sys.dm_audit_actions
WHERE
-- Class_desc -> O nome da classe do objeto ao qual a ao
de auditoria aplica-se
class_desc='DATABASE'
-- Configuration_level ->Indica que a ao ou o grupo de
aes especificado nessa linha so configurveis no nvel do
Grupo ou da Ao
AND configuration_level IN ('Action','Group')
ORDER BY name

Ao criar uma especificao de auditoria de banco de dados, voc atribui um nome, ento associa ao Audit
Specification com o SQL Server Audit Object e especifica o Audit Action Type como foi feito com o Server
Audit Specification. No entanto, alm disso, deve-se especificar o Object Class (database, object ou
schema), o nome do objeto auditado e o security principal (ou seja, quem ns vamos auditar).
Uma vez que o Audit Specification for concludo, voc deve habilitar o SQL Server Audit Object e o Audit
Specification. Apartir da os eventos de auditoria comearo a ser coletados para o target designado.

N OTA 03:

Sintaxe para criar um Database Audit Specification por linha de comando:

CREATE DATABASE AUDIT SPECIFICATION audit_specification_name


{
FOR SERVER AUDIT audit_name
[ { ADD ( { <audit_action_specification> |
audit_action_group_name } )
M V T e c h | 186

SQL Server: Alm do Conceito


Blog Post Collection
} [, ...n] ]
[ WITH ( STATE = { ON | OFF } ) ]
}
[ ; ]
<audit_action_specification>::=
{
action [ ,...n ]ON [ class :: ] securable BY principal [
,...n ]
}

P ASSA A P ASSO DE COMO CRIAR U MA A UDITORIA .


Nesse exemplo vamos configurar os trs targets disponveis para configurar o Server Audit Objects. Iremos
demostrar como fazer isso logo abaixo:

a) O primeiro target que criaremos ser Windows Application Event Log. Abra o Management Studio v
em: Security/ Audits/New Audit. Veja Figura 03.

M V T e c h | 187

SQL Server: Alm do Conceito


Blog Post Collection

Figura

03.

Criao auditoria

A primeira coisa que voc precisa fazer atribuir o nome ou usar o nome que gerado automaticamente.
Preencha a opo Audit Name(aconselho a colocar um nome intuitivo para que possa identificar do que
se trata), no nosso caso estou colocando o nome do target mais a forma que ele esta sendo criado. Ou
seja, ApplicationLog + SSMS = ApplicationLog SSMS . Veja Figura 04.

M V T e c h | 188

SQL Server: Alm do Conceito


Blog Post Collection

Figura 04. Configurao parmetros de auditoria.

Nesse exemplo estamos configurando o Queue delay para 3000 milissegundos. Na Tabela 03 descreve
todos os parmetros existentes na Figura 04.

Parmetros

Descrio

Queue Delay

E informado o valor que indica de quanto em quanto tempo ser


descarregado antes das aes de auditoria serem processadas.
M V T e c h | 189

SQL Server: Alm do Conceito


Blog Post Collection
Se essa opo for selecionada e exista uma tentativa de escrever no
Shut down Server on
arquivo de auditoria e ocorrer uma falha ele vai parar o servio,
audit log failure
evitando assim falhas na auditoria.
Voc pode salvar eventos capturados a qualquer um dos seguintes
destinos
Audit Destination

*File
*Application_Log
*Security_Log

File Path

Se o Audit Destination escolhido foi opo FILE, ento voc precisa


fornecer o caminho onde os arquivos de auditoria sero salvos.

Maximum Rollover

E informado o numero de arquivos que vo ser gerados.

Maximum File Size

Especifica o tamanho mximo de espao em disco reservado para cada


arquivo gerado para auditoria. Voc pode escolher o boto que
especifica a capacidade em MB, GB, TB ou a opo Unlimited(tome
bastante cuidado ao escolher essa alternativa).

Reserve Disk Space

Ativando essa opo voc ira reservar todo espao em disco rgido

M V T e c h | 190

SQL Server: Alm do Conceito


Blog Post Collection
Na opo Audit Destination selecione Application Log. Ao fazer isso os outros parmetros ficaram
indisponveis. Clique em OK. Veja Figura 05.

Figura 05. Escolha do Audit destination.

Por default o Server Audit Object criado desabilitado. Para habilita-lo basta clicar com o boto direito
do mouse em ApplicationLogSSMS e selecionar a opo Enable Audit. Veja Figura 06.

M V T e c h | 191

SQL Server: Alm do Conceito


Blog Post Collection

Figura 06. Habilitar Server Audit Object

Para criar o mesmo Server Audit demostrado acima usando T-SQL basta executar os comandos abaixo:
CREATE SERVER AUDIT [TargetApplicationLogTSQL]
TO APPLICATION_LOG
WITH
(
QUEUE_DELAY = 3000,
ON_FAILURE = CONTINUE
)
GO

O parmetro ON_FAILURE s pode ser configurado para aqueles logins que possuem permisso
SHUTDOWN. Se o usurio que esta tentando executar esse comando no tiver essa permisso, a funo
ir falhar com uma mensagem MSG_NO_SHUTDOWN_PERMISSION.
O segundo objeto que vamos configurar para o Target FILE. Existem algumas opes adicionais que pode
ser especificada. Incluindo qual a pasta que os arquivos de auditoria sero gerados, o nmero mximo de
rollover files(Esse parmetro avaliado sempre que a auditoria reiniciada ou quando um novo arquivo
necessrio porque o MAXSIZE foi atingido. Se o nmero de arquivos excede o MAX_ROLLOVER_FILES o
arquivos mais antigo deletado), o tamanho mximo de cada arquivo e se para reservar espao em
disco para o audit file(arquivo de auditoria).
M V T e c h | 192

SQL Server: Alm do Conceito


Blog Post Collection

F AREMOS ESSAS CONFIGU RAES DO S ERVER A UDIT ATRAVS DE TSQL E O M ANAGEMENT S TUDIO .

Faa os passos descritos no item 1a.


Vamos atribui um nome para opo Audit name. No nosso caso o nome ser: TargetFileSSMS. Veja
Figura 07.

Figura 07. Atribuio do Audit Name .

Por causa do aumento da latncia, devido rede pode ser necessrio aumentar o parmetro
QUEUE_DELAY para evitar afetar a instncia. Colocaremos essa opo como 2000 milissegundos.
Prximo passo ser configurar o Audit Destination. Selecione a opo FILE.
No parmetro File path devemos dizer o nome da pasta onde sero armazenados os arquivos da
auditoria. Neste exemplo estamos especificando a pasta de destino para C: \ Auditoria \.
Em MAX_ROLLOVER_FILES digite 3. Pois ser o numero mximo de arquivos gerados.
Desabilite o check na opo Unlimited do parmetro Maximum file size. Preencha esse campo com
nmero 3 e deixe selecionado o tamanho MB (megabyte).
Por fim, habite Reserve disk space. Veja na Figura 08 como ficaram todas as configuraes.

M V T e c h | 193

SQL Server: Alm do Conceito


Blog Post Collection

Clique no boto OK.

Pronto! O Server Audit foi criado com sucesso. Voc estar se perguntando: Como posso criar o mesmo
objeto atravs de comandos TSQL? Veja logo abaixo o script:
USE master
GO
CREATE SERVER AUDIT TargetFileTSQL
TO FILE
(
M V T e c h | 194

SQL Server: Alm do Conceito


Blog Post Collection
FILEPATH = N'C:\Auditoria',
/*MAXSIZE = Especifica o tamanho mximo para o qual o
arquivo de auditoria pode crescer*/
MAXSIZE = 3MB,
/*MAX_ROLLOVER_FILES = Nmero mximo de arquivos que pode
ser criados. O valor padro UNLIMITED. Lembrando que esse valor
deve ser um nmero inteiro. Portanto o valor UNLIMITED = 0.*/
MAX_ROLLOVER_FILES = 3,
/*RESERVE_DISK_SPACE = Esta opo de pr-aloca o arquivo no
disco para o valor definifo no MAXSIZE. Aplica-se somente se
MAXSIZE no igual a UNLIMITED. O valor padro OFF*/
RESERVE_DISK_SPACE = ON
)
WITH
(
QUEUE_DELAY = 1000,
ON_FAILURE = CONTINUE
)

Para visualizarmos os objetos criados (Veja Figura 09) basta utilizar o seguinte consulta:

/*OBJETOS DE AUDITORIA CRIADOS*/


SELECT * FROM SYS.server_audits

Figura 09. Resultado da consulta em sys.server_audits.

Observe que na coluna type_desc descreve o tipo do target de cada Server Audit.
Por fim o terceiro e ltimo Target Windows Security Event Log. Antes de comeamos a demonstrar como
faremos a criao desse objeto, ser necessrio efetuarmos algumas configuraes no Windows a fim de
permitir que o SQL Server possa gravar eventos no Security Event Log. O servidor utilizado nessa
demonstrao o Windows Server 2008).

Primeiro clicamos no boto Iniciar \Executar\secpol.msc. Veja Figura 10.

M V T e c h | 195

SQL Server: Alm do Conceito


Blog Post Collection

Figura 10.
Clique em Local Polices\ Audit Policy. Com o boto direito do mouse selecione Audit object access\
Properties. Marque as opes: Success e Failure. Estamos permitindo o acesso ao objeto de auditoria em
casos de sucesso e falha. Veja Figura 11.

Figura 11. Propriedades de acesso ao objeto de auditoria

Precisamos atribuir direito de gerar Security Audits para a conta de servio do SQL Server. Caso voc no
lembre ou no saiba qual usurio esta inicializando o SQL Server basta ir em Iniciar \Microsoft SQL Server
2008 R2 \ Configuration Tools \ SQL Server Configuration Maganer. Selecione o servio com o boto
direito e clique em Propriedades. Na aba Logon verifique a conta que est configurada o MSSQLSERVER.
Veja Figura 12.
M V T e c h | 196

SQL Server: Alm do Conceito


Blog Post Collection

Figura 12. Parando o Servio do SQL Server atraves do Configuration Manager.

Depois de descoberto o usurio vamos finalmente atribuir a permisso para ele. Selecione User Rights
Assignment \ Generate security audits. Clique no boto Add User or Group e adicione o usurio
configurado na conta de servio do SQL Server. Veja Figura 13.

M V T e c h | 197

SQL Server: Alm do Conceito


Blog Post Collection

Figura 13. Adicionando usurio da conta de servio do SQL.

Uma vez que estas duas alteraes foram feitas, reinicie o servio do SQL Server e ento voc vai ser capaz
de criar um Server Audit no Windows Security Log. Observe que as opes definidas aqui podem muito
bem serem efetuadas via Group Policy direto no servidor de domnio. Esse tipo de configurao deve ser
discutido com os responsveis pelo gerenciamento das Politicas de Segurana do Servidor e assim garantir
que os ajustes necessrios sejam colocados em vigor para que o SQL Server seja capaz de gravar eventos
no Security Log.

Para criar o Server Audit faa os passos descritos no item 1a.

Atribua um nome no campo Audit Name. O nome que adotaremos ser TargetSecurityLogSSMS.

Por default a opo Queue delay in milliseconds preenchida com o valor 1000. Vamos alterar esse
valor para 2000.

Na opo Audit destination selecione Security Log. Perceba que as outras opes de configurao so
desabilitadas assim que escolhemos essa opo. Veja Figura 14.

M V T e c h | 198

SQL Server: Alm do Conceito


Blog Post Collection

Figura 14. Configurao Audit destination.


Caso tenha interesse em criar esse mesmo Server Audit atravs de comandos TSQL faa conforme script
abaixo:
CREATE SERVER AUDIT TargetSecurityLogTSQL
TO SECURITY_LOG
WITH
(
QUEUE_DELAY = 2000,
ON_FAILURE = CONTINUE
)
GO
M V T e c h | 199

SQL Server: Alm do Conceito


Blog Post Collection
Como vimos nos exemplos acima, extremamente simples criar Server Audit Objects no SQL Server 2008
usando TSQL ou SSMS.

C RIANDO UM S ERVER OU S ERVER A UDIT S PECIFICATION .


Agora que criamos o nosso Server Audit Objects precisamos adicionar especificao de auditoria
correspondente. Se quisermos fazer uma auditoria no nvel de instncia, teremos que criar um Server
Audit Specification. Vamos auditar toda vez que for gerado um backup ou restore no servidor. O nome do
Action Group utilizado nesse exemplo ser BACKUP_RESTORE_GROUP.
Vamos criar o Server Audit Specification. Abra o SSMS v em Security \Server Audit Specification \New
Server Audit Specification.. Veja Figura 15.

Figura 15. Criao do Server Audit Specification.

Preencha o campo Name, nesse exemplo coloquei o nome da especificao de auditoria + action group
= ServerAuditSpecificationBackupRestore. . Estou fazendo isso para facilitar o entendimento de que esta
administrando o servidor de banco de dados, ou seja, ns mesmos.
Na opo Audit devemos preencher com um dos Server Audit Objects criado anteriormente. Nesse caso
vou querer armazenar os dados auditados no Application Log. Selecione a opo
TargetApplicationLogTSQL. Veja Figura 16.

M V T e c h | 200

SQL Server: Alm do Conceito


Blog Post Collection

Figura 16.

No campo Action \Audit Action Type, selecione BACKUP_RESTORE_GROUP. Ao fazer isso as outras opes
de configurao seram desabilitadas. Clique no boto OK. Veja Figura 17.

M V T e c h | 201

SQL Server: Alm do Conceito


Blog Post Collection

Agora vamos habilitar o Server Audit Specification criado, para iniciarmos a coleta dos dados. Podemos
fazer de duas maneiras, clicando com o boto direito em cima do objeto adicionado e selecionando a
opo Enable Server Audit Specification, ou via TSQL. Veja Figura 18.

M V T e c h | 202

SQL Server: Alm do Conceito


Blog Post Collection

Figura 18.

Se fosse atravs de consulta o script ficaria dessa maneira:


ALTER SERVER AUDIT SPECIFICATION
[ServerAuditSpecificationBackupRestore]
WITH (STATE = ON)
GO

Os scripts da Listagem 01 cria um banco de dados, uma tabela, faz a insero dos dados e por fim faz o
backup e um restore para vermos se os dados realmente esto sendo auditados.

M V T e c h | 203

SQL Server: Alm do Conceito


Blog Post Collection
--CRIAR BANCO DE DADOS AUDITORIA
IF (SELECT DB_ID ('AUDITORIA')) IS NULL
BEGIN
CREATE DATABASE AUDITORIA
END
GO
--CRIAR TABELA
CREATE TABLE TABServerSpecification
(ID
Int Identity(1,1) PRIMARY KEY,
Nome VarChar(250)DEFAULT NewID())
INSERT INTO TABServerSpecification DEFAULT VALUES
GO 10000
--FAZER BACKUP DO BANCO AUDITORIA
BACKUP DATABASE Auditoria
TO DISK = 'C:\Auditoria\Auditoria.bak'
WITH FORMAT;
GO
-- DROP NO BANCO AUDITORIA
DROP DATABASE AUDITORIA
--RETORE BANCO DE DADOS AUDITORIA
RESTORE DATABASE AUDITORIA
FROM DISK = 'C:\Auditoria\Auditoria.bak'
WITH RECOVERY
GO

Vamos verificar se o que acabamos de fazer foi realmente auditado, para isso selecione a guia
Management \SQL Server Logs \ View SQL Server Log. Veja Figura 19.

M V T e c h | 204

SQL Server: Alm do Conceito


Blog Post Collection

Figura 19. Visualizao do Log

Selecione a seguinte opo: Windows NT \ Application . Veja Figura 20.

M V T e c h | 205

SQL Server: Alm do Conceito


Blog Post Collection

Figura 20. Dados auditados

Verifique que todas as linhas que possuem uma chave foram os dados auditados, no nosso caso o backup
e o restore que fizemos.

C RIANDO UM S ERVER OU D ATABASE A UDIT S PECIFICATION .


Nos prximo exemplo vamos criar um Database Audit Specification. O objetivo dessa auditoria ser
auditar a utilizao das clausulas SELECT, INSERT, UPDATE e DELETE em duas tabelas de um nico banco
de dados. Voc precisar do AdventureWorks instalado, para isso baixa baixar no site do Codeplex
(http://msftdbprodsamples.codeplex.com/releases/view/55926).
A primeira tarefa criarmos um Server Audit, como ns j criamos na etapa 2b. Utilizaremos mesmo
quando for solicitado.
Para criar um Database Audit Specification voc deve escolher o banco de dados que deseja fazer a
auditoria. No nosso caso ser o AdventureWorks. Clique com o boto direito em Database Audit
Specification e selecione New Audit Specification, como mostrado na Figura 21.

M V T e c h | 206

SQL Server: Alm do Conceito


Blog Post Collection

Figura 21. Criar Novo Database Audit Specification.

Na janela Create Database Audit Specification voc pode aceitar o nome sugerido ou caso queira pode
digitar seu prprio nome. Adotaremos o seguinte:
Em seguida selecione a partir da caixa suspensa o Server Audit Object que armazenaremos os dados da
auditoria. Dessa vez vamos armazenar os dados da auditoria em um arquivo, utilizaremos o Server Audit
Object criado anteriormente. Selecione o Target TargetFileSSMS. Veja Figura 22.

M V T e c h | 207

SQL Server: Alm do Conceito


Blog Post Collection

Figura 22.

Na seo Audit Action Types, voc deve especificar o tipo de ao de auditoria que deseja capturar. No
primeiro combo selecione a opo SELECT, com o objetivo de gravar toda atividade do comando SELECT
para a tabela Veja Figura 23.

M V T e c h | 208

SQL Server: Alm do Conceito


Blog Post Collection

Figura 23.

Agora devemos escolher Object Class. Vamos auditar mais de uma tabela de um banco especifico ento
selecione a segunda opo dessa coluna, ou seja, OBJECT.
Devemos selecionar qual o OBJECT ser auditado, para isto clique no boto da coluna Object Name.
Veja Figura 24.

M V T e c h | 209

SQL Server: Alm do Conceito


Blog Post Collection

Figura 24.

Na janela Select Objects clique no boto Browse


Escolha as tabelas que sero monitoradas do banco AdventureWorks. Selecione as seguintes tabelas:
HumanResources.Employee, Person.Contact, Production.Location e Production.UnitMeasure. Clique no
boto OK (Observe que temos a opo de escolher mais de um database).
A prxima etapa ser escolher o Principal Name, ou seja, qual o usurio que queremos auditar. Nessa
opo podemos selecionar Users e Roles. Para fazer isso, clique no boto ... da coluna Principal Name
e na janela Select Objects clique no boto Browser... Agora voc pode ver quais Principals pode
escolher, nesse caso nos vamos escolher public , pois o objetivo dessa auditoria identificar qualquer
pessoas que execute a clusula SELECT na tabela xx , como mostrado na figura 25.

M V T e c h | 210

SQL Server: Alm do Conceito


Blog Post Collection

Figura 25.

Conclumos o nosso primeiro filtro, vamos repetir as operaes descritas acima para os comandos INSERT,
UPDATE e DELETE. Veja Figura 26.
Clique em OK para concluirmos a criao do Database Audit Specification.
Assim como Server Audit Specification a especificao de banco de dados criado desabilitado, se voc
observe vera que ele tem uma seta vermelha indicando que esta desativada, para habilita-la clique sobre
o mesmo como boto direito e escolha a opo Enable Database Audit Specification.
Agora vamos selecionar excluir, inserir e atualizar alguns registros das tabelas que estamos auditando
para ver se tudo aquilo que configuramos esta funcionando conforme o esperado. Execute os scripts da
Listagem 02.

--AUDITANDO COMANDO SELECT


USE AdventureWorks;
Select
P.FirstName + ' ' + C.LastName AS 'Nome,
M V T e c h | 211

SQL Server: Alm do Conceito


Blog Post Collection
E.VacationHours AS 'Frias (horas)',
E.SickLeaveHours AS 'Afastamento por motivo de doena
(horas)',
E.LoginID AS 'Login'
FROM HumanResources.Employee E LEFT JOIN Person.Contact C ON
E.ContactID = C.ContactID
ORDER BY [Nome Completo];
--AUDITANDO COMANDO SELECT
select * from Production.Location
--AUDITANDO COMANDO UPDATE
Update Person.Contact
Set FirstName = 'Cibelle',
emailAddress =
'rosanacibelle.castrodasilva@studentpartners.com.br'
Where ContactID = 6
--AUDITANDO COMANDO DELETE
DELETE FROM Production.UnitMeasure WHERE Name = 'Boxes'
--AUDITANDO COMANDO INSERT
INSERT INTO Production.Location
Magazine',0.00,0.00,GETDATE())

VALUES ('SQL

Os dados foram armazenadados em um arquivo que foi gerado na pasta C:\Auditoria. Veja Figura 27.

Figura 27. Arquivo de auditoria gerado em um file.

Vamos vizualizar os dados auditados utilizando a funo fn_get_audit_file, que responsvel em retornar
as informaes de um arquivo de auditoria. Execute o script da Listagem 03.

M V T e c h | 212

SQL Server: Alm do Conceito


Blog Post Collection
/*Retorna informaes de um arquivo de auditoria
Sintaxe:
fn_get_audit_file ( file_pattern, {default | initial_file_name |
NULL }, {default | audit_file_offset | NULL } )
*/
SELECT
convert(varchar(10),event_time,103) as [Data], --Data e
hora em que a ao auditvel acionada
convert(varchar(12),event_time,114) as [Hora], --Data e
hora em que a ao auditvel acionada
server_instance_name as [Nome Instncia], --Nome da
instncia de servidor no qual a auditoria ocorreu
database_name as [Nome do Banco], --O contexto do banco de
dados no qual a ao aconteceu. Permite valor nulo. Retorna NULL
para auditorias realizadas no nvel de servidor.
server_principal_name as [Login], --Logon atual. Permite
valor nulo
object_name, --O nome da entidade na qual a auditoria
ocorreu.
statement as [Consulta Executada],
file_name as [Caminho do Arquivo]
FROM
fn_get_audit_file('C:\Auditoria\TargetFileSSMS_D59592D14057-49EB-A421CF2DF6BB2F47_0_129603920978160000.sqlaudit',DEFAULT,DEFAULT)

CONCLUSO
Uma parte essencial de qualquer estratgia de segurana de dados um plano de segurana que possui
regras com a capacidade de rastrear quem acessou ou tentou acessar dados, mas para ter essas
informaes precisamos realizar auditorias regulamente. Isso permite ao DBA a capacidade de detectar
prevenir qualquer ao maliciosa, acessos ilegtimos.
Vimos no decorrer do artigo como criar uma auditoria nos mais diversos seguimentos, vimos tambm que
o SQL Server Audit uma ferramenta poderosa que os DBAs podem utilizar para coletar quase todas as
atividades que acontece dentro dos nossos servidores ou banco de dados ou um objeto especifico.

REFERNCIAS

Compreendendo a auditoria do SQL Server


http://msdn.microsoft.com/pt-br/library/cc280386.aspx
Como criar uma auditoria no nvel do banco de dados
M V T e c h | 213

SQL Server: Alm do Conceito


Blog Post Collection
http://msdn.microsoft.com/pt-br/library/cc280425.aspx
Como criar uma auditoria do nvel de servidor
http://msdn.microsoft.com/pt-br/library/cc280426.aspx
Auditing in SQL Server 2008
http://msdn.microsoft.com/en-us/library/dd392015(v=sql.100).aspx
sys.server_audits (Transact-SQL)
http://msdn.microsoft.com/pt-br/library/cc280727.aspx

M V T e c h | 214

SQL Server: Alm do Conceito


Blog Post Collection

Performance e Desempenho
System Monitor & SQL Profiler

muito comum nos dias de hoje enfrentarmos problemas com desempenho no trabalho ou at mesmo
no conforto de nossa casa. Voc pode est se perguntando como assim? Imagine a seguinte situao:
Uma turma de amigos resolveu marcar um encontro on-line para disputar aquele jogo que acabou de ser
lanado. Caso voc no tenha uma boa placa de vdeo, memria e um processador mais ou menos a
reuniozinha vai ter que ficar para outro dia. Pois o jogo vai ficar lento, a imagem no seu monitor vai ficar
renderizando dentre outas coisas.
Falando no mundo do banco de dados, infelizmente vivemos sujeitos a falhas de hardware, bloqueio de
transaes, paginao, dentre outras coisas que acarretam na degradao das nossas aplicaes.
Resumindo isso tudo que eu disse exatamente quando o Service Desk da sua empresa recebe aquelas
ligaes: O meu sistema no abre nada!!, T muito lento no consigo trabalhar ou melhor A culpa
da TI.
Diante dessa situao, vou abordar nesse artigo como monitorar seu ambiente de SQL Server e a
diagnosticar tais problemas atravs de estudo de caso prtico. O desafio reunir o System Monitor com
o SQL Profiler de uma maneira coerente que nos permita fazer uma anlise eficiente.
Vou criar um cenrio fictcio a fim de ajudar na compreenso dos conceitos. Imaginemos que somos
funcionrios da AdventureWorks e parte das atribuies destinas a ns dentro da empresa, inclui ficarmos
encarregados de monitorar o ambiente de produo. Ou seja, verificar o desempenho do banco de dados
como um todo. Por exemplo: Analisar se est tendo I/O no disco, como est o processador ou a memria
do servidor, quantas conexes esto ativas, e assim por diante.
Ultimamente nosso atendimento nvel 01 est recebendo muitas ligaes reportando problemas de
lentido com as aplicaes. Resolvemos ento investigar o motivo dessas reclamaes.

O QUE O S YSTEM M ONITOR ?


A primeira coisa que vamos fazer utilizar o System Monitor, para coletar as informaes do servidor de
banco de dados.
O System Monitor mostra graficamente os dados em tempo real de desempenho, incluindo a utilizao
do processador, cache, fila de impresso, sincronizao, uso da largura de banda e milhares de outras
estatsticas. Ele utiliza uma arquitetura de sondagem para capturar e registrar dados numricos expostos
pelos aplicativos. O DBA escolhe os contadores a serem capturados para anlise de acordo com a anlise
que ele necessita fazer. No nosso caso vamos escolher os contadores que nos ajudar a identificar o
motivo da queda de desempenho nas aplicaes.

N OTA 1:
M V T e c h | 215

SQL Server: Alm do Conceito


Blog Post Collection
A cada nova verso do Windows s vezes voc tem que procurar as ferramentas que utilizava
anteriormente em um lugar diferente. Porque a Microsoft resolveu mudar o nome da ferramenta ou
mudou de lugar. Por exemplo, o System Monitor o pessoal que trabalha com TI h muito tempo conhece
esse utilitrio como Perfmon, Performance Monitor ou System Monitor.
O nome Perfmon foi dado porque umas das formas de iniciar esse programa acessando o menu iniciar
> executar e digitando na caixa de texto: perfmon.exe. (Fim Nota1)
No entanto para entendermos como obter as informaes desejadas importante compreender os trs
nveis fundamentais para os critrios de monitoramentos. Estes nveis so: object, counter e instance.
Veja a Figura 01.

Figura 01. Contadores de desempenho do Performance Monitor.

OBJECT: Um object um componente, aplicativo ou subsistema dentro de um aplicativo. Por exemplo,


Processor, Network Interface e SQLServer:Databases so todos objects.
COUNTERS: Counters so um subconjunto de um object. Para um determinado object, voc pode ter
vrios contadores. Por exemplo, o object Processor tem vrios contadores para escolher: % Processor
Time, % User Time, Interrupts/sec, etc.
INSTANCES: Cada counter pode ter uma ou mais instances . Usando o exemplo acima do object Processor,
o %Processor Time teria 47 instncias de um sistema - um para cada processador (0 at 47). Caso
necessite, voc tem a capacidade de monitorar apenas uma instncia de um counter de dados.

M V T e c h | 216

SQL Server: Alm do Conceito


Blog Post Collection
N OTA 2:
Lembrando que para que os dados sejam coletados corretamente os nicos tipos de dados permitidos
pelo System Monitor so numricos. (Fim Nota 2)
Antes de criarmos nosso primeiro Data Collector Sets queria chamar ateno para trs contadores em
especial. So eles: System: Processor Queue Length, Network Interface: Output Queue Length e Physical
Disk: Avg Disk Queue Length. Se identificarmos alguma anormalidade neles, teremos srios problemas no
sistema.

System: Processor Queue Length: Este contador, ao invs de avaliar o uso de um nico processador, avalia
o enfileiramento de threads aguardando oportunidade de execuo em todos os processadores. Se ele
excede 02 theads por cada processador durante perodos contnuos ou durante um perodo de
monitorizao de 24 horas, voc poder ter um gargalo de CPU. Por exemplo, se voc possui 06 CPUs no
seu servidor, o valor deste contador no deve ultrapassar quanto? A resposta 12, que equivale ao
seguinte clculo = 06 x 02 = 12. O resultado a multiplicao de 06 CPU's com 02 theads(valor aceitvel
por processador). Se este valor ultrapassado por um perodo muito extenso e constante, pode indicar
que seus processadores no esto mais suportando a carga do sistema.
Network Interface: Output Queue Length: Este contador de desempenho indica o tamanho da fila de
pacotes de sada. Ou seja quantos pacotes esto sendo mantidos em uma fila, esperando para ser
enviada a partir da placa de rede para rede. Geralmente esse valor zero. Como regra geral, se o Output
Queue Length for superior a 2 por um perodo de 10 minutos ou mais de uma vez, provavelmente voc
tem um problema de desempenho de rede e isso est causando gargalo na rede. As possveis causas desse
problema pode estar em vrias coisas como por exemplo: uma placa de rede lenta, um problema de rede,
um problema no hub ou switch, pode ser que o SQL Server muito. muito ocupado e a carga demias
para placa de rede ou at a prpria rede.
Physical Disk: Avg Disk Queue Length: Uma thread pode fazer muitos pedidos de uma vez s ao IO
Manager(O IO Manager orientado a pacotes. Resumindo em poucas palavras, sua funo receber os
pedidos de leitura/gravao dos processos, transformar estes pedidos em um pacote chamado de IRP
IO Request Packet, e encaminhar este pacote ao driver responsvel. Aps feita essa operao, o driver
devolver o IRP ao IO Manager com as informaes de como foi o processamento) sem esperar que a
primeira seja completada. O IO Manager no ir recusar esses pedidos, mas ir organiz-los numa fila,
pois o disco s faz uma coisa de cada vez. O comprimento mdio dessa fila o "Avg Disk Queue Length".
O contador Avg. Disk Queue Length se for superior a dois por perodos contnuos (mais de 10 minutos ou
mais durante o perodo de monitoramento 24 horas) para cada unidade de disco em um array, ento voc
pode ter um gargalo de I/O para esse array. Voc precisar calcular este valor, porque o Performance
Monitor no sabe quantas unidades fsicas esto no seu array. Por exemplo, se voc tem um array de 6
discos fsicos e o Avg Disk Queue Length do disco de 10 para uma disposio particular, ento o Avg.
Disk Queue Length para cada unidade de 1,66 (Clculo: 06/10 = 1,66), que est bem dentro da 2
recomendado por disco fsico.

M V T e c h | 217

SQL Server: Alm do Conceito


Blog Post Collection
Aps a compreenso dos nveis e aprendermos um pouco mais sobre contadores, poderemos em fim criar
o chamado Data Collector Sets, que nada mais do que um bloco de monitoramento onde vamos colocar
nossos counters. A grosso modo um conjunto de dados personalizados onde voc decide quais
atividades sero monitoradas
C OMO CRIAR UM D ATA C OLLETOR S ETS ?

Quando voc usa o System Monitor, possvel ver os contadores de desempenho em tempo real. O Data
Collector Sets pode gravar estes dados para que voc possa analis-lo mais tarde.
Caso tenha um problema de desempenho ou deseja analisar e, possivelmente, melhorar o desempenho
de um servidor, voc pode criar um Data Collector Set para recolher dados de desempenho.
No entanto, para a anlise ser til, aconselho a coletar e salvar os registros dos dados no momento da
queda de desempenho. Mas para que fazer isso? Por que podemos comparar como ficou o desempenho
antes de depois dos ajustes.

P ARA CRIAR UM D ATA C OLLETOR S ETS PERSONALIZADO , SIGA OS PASSOS ABAIX O :

Para iniciar o Performance Monitor clique em Iniciar >Executar e digite: perfmon.exe;


Clique em Data Collector Sets > User Defined, com o boto direito do mouse escolha New e em seguida
Data Collector Sets. Veja a Figura 02;

Figura 02. Primeiro passo para criar Data Collector Sets.


M V T e c h | 218

SQL Server: Alm do Conceito


Blog Post Collection

O wizard para criao do Data Collector Sets ir aparecer socilitando que voc digite um nome. Logo aps
a escolha do nome, teremos duas opes: Create from a template (Recommentded) e Create manually
(Advanced). A opo default Create from a template (Recommentded), mas no nosso contexto vamos
criar manualmente os contadores que queremos monitorar. Deste modo, selecione a segunda opo e
clique em Next. Veja a Figura 03;

Figura 03.Wizard Data Collector Sets

Agora devemos escolher qual tipo de dados iremos incluir no Data Collector Set. A opo Create data log
> Performance Counter j vem selecionada por default, vamos mant-lo assim. Clique em Next. (Figura
04);

M V T e c h | 219

SQL Server: Alm do Conceito


Blog Post Collection

Figura 04. Criar Data Collector Sets

Na prxima tela encontramos as seguintes opes: Performance Counter, Event Trace Data e System
configuration information. Selecione Performance Counter. Essa opo permitir escolher qualquer
contador disponvel no Performance Monitor. Feito isso clique em Next;
Clique no boto Add. Selecione os contadores de performance que voc deseja. Vamos monitorar a fila
atual dos discos (PhisicalDisk\Current Disk Queue Length) e o processador (Processor \%Processor time).
Em seguida clique em OK. Observe a Figura 05;

M V T e c h | 220

SQL Server: Alm do Conceito


Blog Post Collection

Figura 05. Counter PhysicalDisk

Depois de incluir os contadores, o prximo passo definir qual o intervalo que eles sero monitorados.
Veja na Figura 06 que existem duas opes a serem configuradas: Sample interval e Units. Em Sample
interval iremos deixar o nmero 15 e em Units informaremos seconds. Isso ir definir que de 15seg em
15seg ser coletadas as informaes referente aos contadores adicionados no passo anterior. Clique no
boto Finish.

M V T e c h | 221

SQL Server: Alm do Conceito


Blog Post Collection

Figura 06. Intervalo de tempo do Data Collector Sets

Depois de criar um Data Collector Set voc pode salv-lo no diretrio padro
(C:\PerfLogs\Admin\HostName_AnoMesDia) ou escolher outro local da sua preferncia. Veja na Figura
07 que o podemos visualizar o caminho completo ao selecionarmos o SQLMagazine em Data Collector
Sets.

Figura
07.

Diretrio Padro do Data Collector Sets

Com isso nosso coletor de dados est pronto. Para iniciar a armazenamento das informaes basta clicar
com o boto direito no Data Colletor Set > SQLMagazine e escolher opo Start. Observe a Figura 08.
M V T e c h | 222

SQL Server: Alm do Conceito


Blog Post Collection

Figura 08. Iniciar Data Collector Sets


Para verificarmos se a coleta comeou, selecione Reports > User > Defined >SQL Magazine. Veja a Figura
09.

Figura 09. Relatrio Performance Monitor

M V T e c h | 223

SQL Server: Alm do Conceito


Blog Post Collection

M V T e c h | 224

SQL Server: Alm do Conceito


Blog Post Collection
SQL SERVER PROFILER

O Microsoft SQL Server Profiler uma interface grfica para a funcionalidade de Rastreamento, com ele
voc pode capturar a atividade gerada por uma carga de trabalho em uma instncia do SQL Server ou do
Analysis Service.
Podemos utilizar os dados capturados para monitorar os erros de uma instncia ou problemas de
concorrncia, como tambm capturar dados que so usados para otimizar o desempenho das consultas
que so executadas no ambiente, seja ele de produo ou de teste.
Para dar continuidade na resoluo do problema de performance na aplicao da empresa
AdventureWorks vamos utilizar o Profiler. Vamos criar um trace e fazer uma interseo entre os
contadores do Performance Monitor com os dados retornados no trace.

O QUE O T RACE ?
SQL Server Profiler o responsvel por criar o chamado Trace. Estes traces incluem todos os scripts T-SQL
que so executados simultaneamente no SQL Server, quanto tempo eles esto levando, o tipo de
bloqueios sendo usado,e quaisquer erros que possam ocorrer no servidor monitorado.
Como o Trace contm todos os scripts T-SQL em execuo no SQL Server, muitas vezes tende a se tornar
consideravelmente grande. Por isso, sempre uma boa prtica capturar apenas os dados que so
realmente necessrios para anlise.
Embora voc possa criar um trace usando Transact-SQL (T-SQL), mais comum usar SQL Server Profiler
para isso. E como fazer isso? Voc pode iniciar o SQL Server Profiler atravs do menu File >New Trace do
SQL Server 2008 e em seguida se conectar em uma instncia para comear a configurar um Trace. Veja
na Figura 10.

M V T e c h | 225

SQL Server: Alm do Conceito


Blog Post Collection

Figura 10. Criao Trace


Todo trace obrigado a ter um nome e pelo menos um evento. Podemos especificar vrias propriedades
para um Trace, como por exemplo: nome, modelo, hora de parada, tamanho mximo do arquivo e etc.
Veja Figura 11 .

Figura 11. Propriedades Trace

M V T e c h | 226

SQL Server: Alm do Conceito


Blog Post Collection
Muitas pessoas ignoram os Templates que o SQL Server Profiler fornece. O conhecimento sobre cada um
deles nos permite fazer uma anlise til dos traces. O SQL Server Profiler oferece esses modelos de
rastreamento predefinidos que permitem facilmente configurar as event classes que provavelmente
especificaremos no trace. Na tabela 1 descreve os templates prontos que pode ser utilizado para
rastreamentos sem qualquer modificao ou como ponto de partida para um novo onde podemos
adicionar colunas e eventos diferentes do padronizado.

Template
Blank

Objetivo
Um trace est vazio, ou seja, no possui nenhum evento ou coluna
selecionados para o rastreamento. Permite criar um rastreamento
inteiro a partir do zero.
SP_Counts
Captura cada stored procedure executada para determinar o quanto
cada procedure est sendo executada.
Standard
o template mais comum para comear pois j possui alguns eventos
slecionados. Captura os seguintes eventos: Security Audit, Sessions,
Stored Procedures e TSQL.
TSQL
Captura uma lista de todas as stored procedures e ad hoc SQL batch
executados, mas no inclui estatsticas de desempenho.
TSQL_Durantion
Captura a durao de cada stored procedure e ad hoc SQL batch
executado.
TSQL_Grouped
Captura login e logout, junto com as stored procedures e todas as
instrues Transact-SQL no momento em que foram emitidos. Use para
investigar consultas de um determinado cliente ou usurio. No inclui
dados de desempenho.
TSQL_Locks
Captura informaes de bloqueio e deadlock, como blocked processes,
deadlock chains, grficos de deadlock, lock escalation e lock timeouts.
TSQL_Replay
Capta informaes detalhadas sobre o Transact-SQL . Se necessrio o
rastreamento pode repetido nos servidores ou diferentes. Este template
comumente usado para fazer testes de carga e regresso. Por exemplo:
realizar testes de benchmark.
TSQL_SPs
Capta informaes detalhadas sobre todos as Stored Procedures em
execuo. Use para analisar os passos de componentes dos
procedimentos armazenados. Adicione o evento SP: Recompile se voc
suspeitar que os procedimentos esto sendo recompilados.
Tuning
Captura as informaes sobre procedimentos armazenados TransactSQL e execuo do lote. Use para produzir sada do trace que o Database
Engine Tuning Advisor pode usar como uma workload para ajustar
bancos de dados.
Tabela 1. Descrio Templates.

Por padro, quando um trace iniciado usando o SQL Profiler, todos os eventos aparecem em uma grid
dentro da interface. Podemos observe na Figura 12 como os eventos so listados no Trace.
M V T e c h | 227

SQL Server: Alm do Conceito


Blog Post Collection

Figura 12. Events Selection


N OTA 4:
Podemos salvar os dados de um trace em uma tabela, em um arquivo ou em ambos. (Fim da Nota 4)
Voc pode encontrar mais de 200 eventos que podem ser capturados no Trace SQL. A principal ao para
configurar um rastreamento a seleo do conjunto de eventos que precisa ser monitorado. Tais eventos
so classificados em 21 grupos, alguns podem contem mais de 40 eventos. Os grupos de evento
disponveis esto listados na Tabela 2.

Event Group
Broker
CLR
Cursors
Database

Deprecation
Errors and Warnings

Objetivo
13 eventos para mensagens, filas e conversaes do Service
Broker.
01 evento para o carregamento de Common Language
Runtime(CLR) assembly.
07 eventos para criao, acesso e remoo de cursores.
06 eventos para crescimento/diminuio (grow/shirink) de
arquivos de dados/log (data/log), bem como mudanas de estado
do Database Mirroring.
02 eventos para notificar quando um recurso deprecated usado
dentro da instncia.
16 eventos para erros, avisos e mensagens de informao que
esto sendo registradas. Eventos para detectar pginas suspeitas,
processos bloqueados e estatsticas ausentes em colunas.

M V T e c h | 228

SQL Server: Alm do Conceito


Blog Post Collection
Full Text

03 eventos para monitorar o andamento do progresso de um


ndice full text.
Locks
09 eventos de aquisio, escalation,liberao e deadlocks.
OLEDB
05 eventos para distributed queries (consultas distribudas) e
chamadas de stored procedure.
Objects
03 eventos que monitoram quando um objeto criado, alterado
ou eliminado (dropped).
Performance
14 eventos que permitem capturar show plans, uso de diretrizes
de plano e paralelismo. Este grupo de eventos tambm permite
capturar consultas full text.
Progress Report
01 evento para progresso de criao de ndice online.
Query Notifications
04 eventos para monitorar os parmetros, subscriptions e
templates de notificao de consultas.
Scans
02 para monitorar quando uma tabela ou ndice percorrido.
Security Audit
44 eventos para monitorar o uso de permisses, impersonation,
alteraes em security objects (objetos de segurana),aes de
gerenciamento executadas em objetos, start/stop de uma
instncia e backup/restore de um banco de dados.
Server
03 eventos para a montagem de uma fita, alterar para a memria
do servidor e fechar um trace file (arquivo de rastreamento).
Sessions
03 eventos para conexes existentes quando o trace inicia, assim
como para monitorar a execuo de logon triggers e funo de
classificao no Resource Governor.
Stored Procedures
12 eventos para execuo de uma stored procedure, cache usage,
recompilao e instrues dentro de um procedimento
armazenado (stored procedure).
Transactions
13 eventos para begin, save, commit e rollback de transaes.
TSQL
09 eventos para execuo de chamadas ad hoc T-SQL ou XQuery.
Evento para um lote SQL inteiro, assim como para cada instruo
dentro de um lote.
User Configurable
10 eventos que voc configurar com o SQL Trace.
Tabela 2. Conjunto de Eventos.

Os grupos mais utilizados so: Locks, Performance, Security Audit, Stored Procedures, e TSQL. Os grupos
de evento Stored Procedures e TSQL geralmente so capturados com eventos do grupo Performance para
ter um parmetro e solucionar problemas de desempenho de consulta. O grupo de eventos Security Audit
usado para definir auditoria rapidamente entre uma variedade de eventos de segurana embora a nova
feature de especificao de auditoria fornea recursos mais seguros e flexveis. Por fim os eventos do
grupo Locks so comumente usados para solucionar problemas de concorrncia.
Como dito anteriormente, preciso ter cuidado com quais eventos monitorar, pois alguns deles podem
ter uma carga significativa em uma instncia. Os eventos que se deve ter muito cuidado so:
Performance | Showplan
M V T e c h | 229

SQL Server: Alm do Conceito


Blog Post Collection
Stored Procedures | SP: StmtCompleted
Stored Procedures | SP: StmtStarting
TSQL | StmCompleted
TSQL | StmStarting

Esses grupos de eventos devem ser includos em um trace se e somente se, estiverem em conjunto com
um ou vrios filtros restritivos, que limite o trace a um nico objeto ou string.

C OMO APLICAR FILTROS NO SQL P ROFILER ?


Aps toda essa explicao sobre o que Profiler, trace, template e grupo de eventos vamos ver como
adicionar filtros em um trace para finalmente comearmos a por a mo na massa e resolvermos o
problema da AdventureWorks.
Um filtro essencialmente uma clusula WHERE aplicada nos dados na API do SQL Trace. Os filtros
permitem especificar vrios critrios a serem aplicados nas colunas de dados.
As colunas que possuem character (dados alfanumricos) permitem que filtros sejam definidos em uma
string, usando LIKE ou NOT LIKE, que podem conter um ou mais caracteres curingas. Ver Figura 13.

Figura 13. Aplicando filtros no Trace.

M V T e c h | 230

SQL Server: Alm do Conceito


Blog Post Collection
As colunas de dados baseadas em tempo permitem especificar maior que ou menor que. As colunas de
dados numeric permitem especificar igual, diferente, maior ou igual e menor ou igual. As colunas de dados
binrios no podem ser filtradas.
Mltiplos filtros para uma nica coluna so tratados com a condio OR. Por outro lado os filtros que
possuem vrias colunas so tratados com a condio AND.

Voc pode iniciar, parar e fazer uma pausa em um trace. Depois que foi iniciado o SQL trace retorna os
eventos correspondentes a sua necessidade e descarta os eventos que no correspondem aos critrios
dos filtros selecionados. Quando um trace parado, toda a coleta de eventos termina e, se o trace for
reiniciado, todos os dados anteriores do trace so apagados da tela do Profiler. Caso queira suspender a
coleta de dados temporariamente, voc pode pausar o trace. Quando tirar do pause os eventos
subsequentes so anexados no final da tela do Profiler.

P ERFORMANCE X M ONITORAMENTO
O SQL Trace usado para coletar informaes que ocorrem dentro de uma instncia do SQL Server. O
System Monitor usado para coletar performance counters que fornece o estado dos recursos de
hardware e outros componentes em execuo no servidor. O SQL Server no pode funcionar sem acessar
os recursos de hardware. O estado desses recursos afeta o funcionamento de um servidor SQL Server. Por
exemplo, uma query pode estar sendo executada lentamente, mas o Profiler s informa o quanto ela est
lenta. Porm, adicionando os contadores de desempenho (performance counters) voc poderia encontrar
a razo que estaria fazendo a query estar lenta. Nesse caso o motivo porque no existem recursos de
processamento suficientes.
Embora seja possvel diagnosticar um problema usando somente System Monitor ou o SQL Trace, quando
usamos simultaneamente os dois conjuntos de dados ambos fornecem o contexto para qualquer anlise.

D ICA :
Voc s poder correlacionar um couter log (System Monitor) com um trace file (SQL Profiler) se tiver
capturado a coluna de dados StartTime no trace.

C RIANDO T RACES
Vamos configurar um trace para estabelecer um parmetro de desempenho para verificar a execuo das
querys no banco de dados afim de descobrirmos o motivo de lentido na aplicao.
Para fins de demonstrao adotaremos o banco exemplo da Microsoft o AdventureWorks. Caso ainda no
os possua voc poder baixar as bases de dados AdventureWorks2008 e AdventureWorksDW2008 no
site do Code Plex.
M V T e c h | 231

SQL Server: Alm do Conceito


Blog Post Collection

Inicie o Profiler. Selecione File > New Trace e conecte-se em sua instncia.
Especifique o nome do para: SQL Magazine Trace, template: Blank e opes para salvar em um arquivo,
como mostrado na Figura 14.

Figura 14.Edio do Trace.

Clique na guia Events Selection.


Marque os eventos Lock: DeadLock graph e TSQL: SQL:BatchCompleted. Ver Figura 15.

M V T e c h | 232

SQL Server: Alm do Conceito


Blog Post Collection

Figura 15.Selecionando os Events Selection


Clique em Column Filters e especifique o filtro DatabaseName: AdventureWorks e Duration > Greater than
or equal: 10000. Ver Figura 16.

Figura 16. Editando os filtros do trace.

M V T e c h | 233

SQL Server: Alm do Conceito


Blog Post Collection
Clique em Run.
Inicie o System Monitor clicando em Iniciar > Executar. Digite: perfmon.exe.
Crie um Data Colletor Sets e adicione os seguintes contadores: PhisicalDisk\Current Disk Queue Length,
PhisicalDisk\%Disk Time e Processor\%Processor Time.
Inicie o Data Collector Sets.
Abra o SQL server Management Studio(SSMS), conecte-se na instncia e execute as seguinte query.

USE AdventureWorks
GO
--CRIAO DA TABELA DE TESTE
CREATE TABLE TabTeste(
ID INT IDENTITY(1,1) PRIMARY KEY,
Nome VARCHAR(250) DEFAULT NEWID()
)
-- INSERT DE 10000 REGISTROS
SET NOCOUNT ON
GO
INSERT INTO TabTeste DEFAULT VALUES
GO 10000

Comente o cdigo anterior e escreva as seguintes linhas de cdigo e execute.

DECLARE @I INT
SET @I = 0
WHILE @I < 1000000
BEGIN
IF EXISTS (SELECT ID FROM TabTeste WHERE ID = @I)
BEGIN
PRINT 'ENTROU NO LOOP'
END
SET @I = @I + 1
END
GO

Abra uma new query e execute o cdigo a seguir.

M V T e c h | 234

SQL Server: Alm do Conceito


Blog Post Collection

/*Listagem 1

Update em Production.Product */

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE*


GO
BEGIN TRANSACTION
UPDATE Production.Product
SET ReorderPoint = 898
WHERE ProductID = 317
WAITFOR DELAY '00:00:11'

Adicione mais uma new query e execute o cdigo a seguir:

/*Listagem 2 Update em Production.ProductInventory e um


Select em Production.Product */
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
GO
BEGIN TRANSACTION
UPDATE Production.ProductInventory
SET Quantity = 655
WHERE ProductID = 317
AND LocationID = 1
SELECT
Name,
ReorderPoint
FROM
Production.Product
WHERE
ProductID = 317

Volte para a janela da primeira query e execute o cdigo a seguir:

/*Listagem 3 - Select em Production.ProductInventory */


SELECT
*
FROM
Production.ProductInventory
WHERE
ProductID = 317
AND LocationID = 1

M V T e c h | 235

SQL Server: Alm do Conceito


Blog Post Collection
Ir ocorrer um erro de deadlock. Ver Figura 17. Conforme mensagem abaixo:

Msg 1205, Level 13, State 51, Line 1


Transaction (Process ID 54) was deadlocked on lock resources with another process and has been chosen
as the deadlock victim. Rerun the transaction.

Figura 17. Erro de DeadLock no SSMS .

Verifique no Profile o grfico gerado pelo deadlock. Ver Figura 18.


Figura 18.Grfico do DeadLock .

M V T e c h | 236

SQL Server: Alm do Conceito


Blog Post Collection

Pare o Data Collector Sets que voc criou no item 8.


Pare o Profiler e salve o trace.
Inicie o Profile novamente e selecione File > Open > Trace File.
Selecione o trace que voc salvou.
Clique em File > Import Performance Data. Selecione o counter log criado no System Monitor.
Na janela Performance Counters Limit Dialog, selecione Processor: %Processor Time, .PhysicalDisk:
%DiskTime e Avg.Disk Queue Length. Ver Figura 19.

M V T e c h | 237

SQL Server: Alm do Conceito


Blog Post Collection

Figura 19. Performance Counters Limit Dialog.

Percorra o trace no painel superior e observe as alteraes que ocorreram dentro no grfico do
performance counter e do rastreamento do Profiler. Ver Figura 20.

Figura

20.Unio entre Performance Monitor e o SQL Profiler.


M V T e c h | 238

SQL Server: Alm do Conceito


Blog Post Collection

Conforme podemos observar no grfico da Figura 16 o maior consumo de CPU foi consulta que contm
o loop. medida que vamos selecionando as linhas do trace o curso que tem no grfico vai
movimentando-se a fim de mostrar exatamente estava acontecendo no banco de dados. Com isso
conseguimos identificar que o problema de performance da empresa AdventureWorks uma consulta
mal escrita que est entrando em um loop e mais que isso existe uma outra query que est provocando
deadlock os dois problemas juntos acontecendo vrias vezes durante o dia acarretou nas constantes
reclamaes ao nosso suporte de primeiro nvel. A soluo para esse problema a correo de ambas as
consultas.

D ICA *:
Os nveis de isolamento afetam a maneira como o SQL Server manipula as transaes, assim como a
durao dos locks acquired(bloqueios adquiridos). O SQL Server possui cinco nveis de isolamento o que
estamos utilizando nesse exemplo o READ SERIALIZABLE. Esse nvel de isolamento emula a execuo
serial das transaes, como se todas as transaes fossem executadas uma aps a outra, em srie, em vez
de simultaneamente. Nenhuma outra transao pode modificar dados que foram lidos pela transao
atual at que a transao corrente terminar.

CONCLUSO

Apresentamos nesse artigo o que o Performance Monitor, quais os principais contadores de


desempenho, como captur-los e como analisar os resultados obtidos. Vimos tambm o SQL Profiler, seus
principais grupos, templates e filtros.
Por fim, podemos observar que a unio dessas duas ferramentas nos ajuda a ter uma viso muito mais
ampla dos problemas que esto acontecendo na base de dados.
Como podemos observar so muitas variveis a serem consideradas, mas o que vai influenciar na escolha
dos contadores ou eventos vai ser o problema que estamos enfrentando. No caso demonstrado no artigo
a dificuldade que a empresa enfrentava era perca de desempenho, mas poderia ser a rede mal
configurada ou um gargalo de CPU, memria, disco e etc. Por isso, deve-se tomar muito cuidado na hora
de averiguar os diversos cenrios aparecem no dia a dia, porque a soluo do problema vai depender de
uma avaliao bem feita.

REFERNCIAS

Monitoring (Database Engine)


M V T e c h | 239

SQL Server: Alm do Conceito


Blog Post Collection
http://msdn.microsoft.com/en-us/library/bb510705.aspx
SQL SERVER Introduction to SQL Server 2008
http://blog.sqlauthority.com/2009/04/24/sql-server-introduction-to-sql-server-2008-profiler/
Using SQL Server Profiler
http://msdn.microsoft.com/en-us/library/ms187929.aspx
SQL Server - Introduction to SQL Server 2008 Profiler.
http://blog.sqlauthority.com/2009/08/03/sql-server-introduction-to-sql-server-2008-profiler-2/
SQL Server Profiler Templates
http://msdn.microsoft.com/en-us/library/ms190176.aspx
Code Plex (Baixar AdventureWorks 2008):
http://www.codeplex.com/MSFTDBProdSamples/Release/ProjectReleases.aspx?ReleaseId=18407.
Training Kit 70-432

M V T e c h | 240

SQL Server: Alm do Conceito


Blog Post Collection

Restore Database com SSIS


Ol Pessoal!
O post de hoje ser sobre uma das tarefas fundamentais de um administrador de banco de dados (DBA)
que garantir que os dados possam ser recuperados no caso de um desastre. No nosso dia a dia,
adquirimos vrias coisas que possam nos deixar tranquilos com nossos bens como por exemplo uma
aplice de seguro para carro ou para sua casa. Apesar de caro e rezarmos para nunca usarmos uma
maneira que escolhemos para nos assegurar contra qualquer imprevisto. Enfim, voltando para o nosso
assunto, os backups so as aplices de seguro contra qualquer eventualidade na empresa em que
trabalhamos. O backup ser o responsvel por recuperarmos os dados que foram perdidos e no final das
contas o negcio voltar a fazer as suas operaes empresariais rotineiras. Costumo dizer que ele o
responsvel pelo final feliz de qualquer situao. (rsrs).
Muitas vezes precisamos fazer um restore de uma base em um ambiente diferente do que ns temos,
seja ele para fins de teste de backup ou para um ambiente de homologao para que a equipe de
desenvolvimento faa seus testes antes de subir uma verso nova. Nesses casos existem diversas formas
de resolver o problema como fazer um backup remoto e trazer a base para o ambiente que voc precisa
ou criar um job para fazer um backup copy only e depois fazer o restore a partir do arquivo gerado. Nesse
post para de atender essa necessidade criaremos um pacote para fazer um restore atravs de um FTP que
encontra-se em um servidor de domnio diferente para isso utilizaremos o SSIS, WINSCP e um pouco de
powershell.No final da criao do pacote, o mesmo ficar assim:

M V T e c h | 241

SQL Server: Alm do Conceito


Blog Post Collection

FTP COM W IN SCP

Para configurar os FTP devemos primeiro instalar o WinSCP e configurar um site. A imagem abaixo mostra
como ficar aps essa configurao:

Agora vamos criar um arquivo de texto contendo os seguintes passos:


Abrir o site criado no WinSCP;
Encontrar o arquivo de backup;
Copiar o arquivo para o diretrio na mquina onde ser feito o restore
A criao desse arquivo de texto ser o que o WinSCP utilizar para pegar o arquivo no diretrio que foi
definido para o backup ser salvo e lev-lo para a pasta no outro servidor onde ser feito o restore.
Abra o notepad e coloque o seguinte script:

M V T e c h | 242

SQL Server: Alm do Conceito


Blog Post Collection

option batch on
option confirm off
open FTP_DATABASE
get
/BACKUP/DATABASE/NOME_DATABASE_FULL_201411301300.BAK
S:\RESTORE\RESTORE_DATABASE\
exit

Agora com o SQL Server Data Tools aberto vamos colocar um Execute Process Task e configurar as
propriedades: Executable, Arguments e WorkingDirectory.

M V T e c h | 243

SQL Server: Alm do Conceito


Blog Post Collection

Executable
Arguments
WorkingDirectory

C:\Program Files (x86)\WinSCP\WinSCP.exe


-script=C:\FTP\ftpdatabase.txt
C:\Program Files (x86)\WinSCP

E XECUTE P ROCESS T ASK


Para alterarmos o nome do arquivo no .txt criado no WINSCP, utilizaremos um pouco de powershell. A
necessidade da adio desse passo porque precisamos recuperar o nome do arquivo exato que o FTP
ir copiar para o diretrio S:\RESTORE\RESTORE_DATABASE.
A primeira coisa a fazer pegar um o Execute Process Task e arrastarmos para o Control Flow, conforme
imagem abaixo:

M V T e c h | 244

SQL Server: Alm do Conceito


Blog Post Collection

Antes de modificarmos o Execute Process Task, vamos criar o script para modificarmos o arquivo de
texto. A lgica simples:
Vamos abrir o diretrio onde encontra-se o .txt;
Procurar a palavra COLOCARDATAAQUI;
Substituir ela por uma data (A data especificada nesse caso a data que o backup full foi criado);
Salvar o arquivo;

Abra o Windows PowerShell ISE (http://technet.microsoft.com/en-us/library/dd819514.aspx), conforme


a imagem abaixo:

O script para modificar o arquivo de texto :

M V T e c h | 245

SQL Server: Alm do Conceito


Blog Post Collection

Script:
(Get-Content C:\FTP\ftpdatabase.txt) |
ForEach-Object
{$_
-replace
"COLOCARDATAAQUI",
Date).AddDays(-1).ToString("yyyyMMdd")} |

(Get-

Set-Content C:\FTP\ftpdatabase.txt;

Onde:
Get-Content = Ler e exibir o
contedo de um arquivo de
texto de forma rpida.

ForEach-Object=
Fornece
uma
maneira para percorrer e executar
uma ao.

Retorna
do
dia
anterior,
com
o
formato yyyyMMdd

Uma vez feito o script salve o mesmo com a extenso .ps1, no nosso caso foi salvo no mesmo diretrio
que est o arquivo de texto.
Clique com o boto direito para abrir a caixa de propriedade do Execute Process Task e vamos preencher
os valores e argumentos necessrio para editar o arquivo. Na opo Process do Execute Process Task
Editor vamos alterar os campos Executable e Arguments, conforme imagem abaixo:

M V T e c h | 246

SQL Server: Alm do Conceito


Blog Post Collection

Executable
Arguments

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
-ExecutionPolicy ByPass -command ". 'C:\FTP\ftppowershell.ps1'"

C RIAO VARIVEIS NO SSIS

Vamos criar algumas variveis que iro armazenar o nome do arquivo e o diretrio que iremos utilizar
para fazer o restore. No menu do SSIS, clique em Variveis ou clique com o boto direito em qualquer
lugar do Control Flow e selecione a opo Variables.

M V T e c h | 247

SQL Server: Alm do Conceito


Blog Post Collection

Clique em 'Add Variable' e atualize os valores nas colunas name, Data Type e Value. Conforme imagem
abaixo:

F OREACH L OOP C ONTAINER


Vamos utilizar um Foreach Loop Container, o mesmo muito til em situaes onde necessrio
percorrer uma pasta para fazer carga de arquivos ou fazer uma tarefa onde ter que verificar uma lista
mais de uma vez. D dois cliques no Foreach Loop Container Task para abrir a janela de configurao e
selecione a opo Colletion. Altere o caminho da pasta para S:\RESTORE\RESTORE_DATABASE (Crie
essa pasta caso no exista). Altere o tipo dos arquivos para *.bak .

M V T e c h | 248

SQL Server: Alm do Conceito


Blog Post Collection

Na guia Variable Mappings selecione a varivel User::NM_ARQUIVO na coluna Variable. O Index 0 mapeia
o resultado do primeiro (e nico) enumerador do Foreach. Clique em OK.

M V T e c h | 249

SQL Server: Alm do Conceito


Blog Post Collection

E XECUTE SQL T ASK (DELETE DATABASE)

Vamos adicionar um Execute Script Task para darmos alteramos a base para SINGLE_USER, conforme
imagem abaixo:

Script:
USE MASTER
GO
IF
EXISTS
(SELECT
1
FROM
SYS.DATABASES
WHERE
'NOME_DO_DATABASE')
ALTER DATABASE NOME_DO_DATABASE SET SINGLE_USER WITH
IMMEDIATE
GO
M V T e c h | 250

NAME

ROLLBACK

SQL Server: Alm do Conceito


Blog Post Collection
Script Task (NM_ARQUIVO)
Vamos adicionar a "Script Task" no pacote SSIS e voc configur-lo abrindo o Script Task Editor. Na opo
General, voc deve fornecer um nome e uma descrio para a tarefa. Em seguida, v para opo "Script"
do editor para configurar as propriedades.

A primeira propriedade que voc precisa definir ScriptLanguage. Voc pode criar seus scripts em uma
das duas lnguas: Visual Basic 2010 ou Visual C# 2010. Iremos usar o C#, para o verificarmos se o nome do
arquivo e o diretrio do backup esto corretos.
A prxima propriedade EntryPoint. Este o mtodo (especfico para a linguagem de script selecionado)
que o tempo de execuo SSIS chama como o ponto de entrada em seu cdigo. O mtodo Main, na
maioria dos casos, deve funcionar bem.
As prximas duas propriedades na pgina Script so ReadOnlyVariables e ReadWriteVariables. Como os
nomes sugerem, voc digita o nome de todas as variveis SSIS que voc deseja usar em seu script. (Separe
M V T e c h | 251

SQL Server: Alm do Conceito


Blog Post Collection
os nomes com vrgulas para mltiplas variveis de qualquer tipo.) Vamos adicionar a varivel
User::NM_ARQUIVO a propriedade ReadOnlyVariables e a varivel User::CAMINHO_ARQUIVO
propriedade ReadWriteVariables. Como resultado, o meu script C# ser capaz de recuperar a o diretrio
de backup a partir das variveis.
Clique em Edit Script... Ser aberta uma pgina no Visual Studio para programar o que voc precisa, no
nosso caso vamos editar o mtodo Main().

Script:

public void Main()


{
// TODO: Add your code here
String nome;
Dts.Variables["CAMINHO_ARQUIVO"].Value
Dts.Variables["NM_ARQUIVO"].Value.ToString();
nome
Dts.Variables["CAMINHO_ARQUIVO"].Value.ToString();
M V T e c h | 252

=
=

SQL Server: Alm do Conceito


Blog Post Collection
MessageBox.Show(nome);
Dts.TaskResult = (int)ScriptResults.Success;
}

E XECUTE SQL T ASK (RESTORE DATABASE / USER PERMISSION)

Vamos adicionar mais dois Execute SQL Task. No primeiro task ser a procedure que faz o restore
recebendo o diretrio como parmetro.

Script:
EXECUTE [DBO].[USP_RESTORE_DATABASE] ?

E no segundo Execute SQL Task ser as permisses para o usurio que acessa a base restaurada.
M V T e c h | 253

SQL Server: Alm do Conceito


Blog Post Collection

Script:

USE NOME_DO_DATABASE
GO
IF EXISTS (SELECT 1 FROM NOME_DO_DATABASE.sys.database_principals
WHERE name = N'user')DROP USER [caedbh]
GO
CREATE USER [user] FOR LOGIN [user] WITH DEFAULT_SCHEMA=[dbo]
GO
M V T e c h | 254

SQL Server: Alm do Conceito


Blog Post Collection
SP_ADDROLEMEMBER 'db_datareader', 'user'
GO
SP_ADDROLEMEMBER 'db_datawriter', 'user'
GO

E XECUTE P ROCESS T ASK (MODIFY NAME FTP FILE)


Por fim, iremos colocar outro Execute Process Task para alterar a data colocada no arquivo de texto
responsvel de passar o nome do arquivo de backup no FTP. O objetivo dessa task fazer como que da
prxima vez que o pacote for executado o powershell contido no objeto MODIFY FTP FILE encontre a
palavra COLOCARDATAAQUI, para isso basta criar outro arquivo .ps1 e alterar a ordem do script.

Script:

(Get-Content C:\FTP\ftpdatabase.txt) |
ForEach-Object
{$_
-replace
(Get-Date).AddDays(1).ToString("yyyyMMdd"), "COLOCARDATAAQUI"} |
Set-Content C:\FTP\ftpdatabase.txt;

Com a modificao do nome do arquivo conclumos o post com a criao do pacote para restore de bases
via FTP. Espero que todos tenham gosto e qualquer, duvida ou critica s entrar em contato.

M V T e c h | 255

SQL Server: Alm do Conceito


Blog Post Collection

Leandro Ribeiro
www.sqlleroy.com

Fragmentao do Transaction Log - Parte I


Constantemente, apesar de um vasto material sobre o assunto na net, me deparo com problemas de
configurao do Transaction Log, tais como:
Arquivos de Logs armazenados no mesmo disco que o arquivo de Dados.
Uso de nvel de RAID no recomendado.
Falta de espao em disco motivado pelo crescimento do arquivo de log.
Mas principalmente, Arquivos de Log fragmentados.
A fragmentao do Transaction Log um problema silencioso em seu ambiente e geralmente ocorre
devido a configuraes erradas para o arquivo do Transaction Log e em muitos casos, a utilizao de
configurao padro (1MB para FileSize e AutoGrowth de 10%) para o arquivo de log, atravs de um
CREATE DATABASE simples.
Este assunto motivou a ltima palestra que fiz com meu amigo Marcus Vincius Bittencourt [Twitter | Blog]
no SQL Saturday 147 em Recife e abordarei neste post.
Espero que ajude a algum.

INTRODUO
Antes de entrarmos no universo do Transaction Log, preciso fazer uma pequena introduo de como os
dados so trabalhados pelo SQL Server.
O Database Engine utiliza dois tipos de gravaes: Lgica e Fsica.
A gravao lgica ocorre quando os dados so alterados em uma pgina do Buffer Cache.
A gravao fsica ocorrendo quando a pgina armazenada no disco a partir do Buffer Cache.
A partir desta afirmao, temos a seguinte lgica de alterao de uma informao:
Se o dado a ser alterado no est em memria, ele lido do disco e armazenado no Buffer Cache.
A alterao efetuada no Buffer cache e a pgina marcada como dirty pages (pgina suja).
O Database Engine utiliza o protocolo Write Ahead Log (WAL) para garantir que as dirty pages sejam
armazenadas primeiro no Transaction Log antes de serem persistidas em disco.
M V T e c h | 256

SQL Server: Alm do Conceito


Blog Post Collection
As dirty pages so armazenadas em disco de modo assncrono atravs dos processos Eager
Writing, Lazy Writing e Checkpoint.

A imagem abaixo, ilustra o que foi dito acima.

T RANSACTION L OG
De posse da informao de como os dados so persistidos, temos ideia da carga de trabalho do
Transaction Log que o caracteriza como um componente crtico do SQL Server.
Toda alterao realizada em um Database registrada nele.
Alm de registrar as alteraes e garantir o ACID, o Transaction Log utilizado em:
Database Mirroring
Log Shipping
Replicao Transacional
...
No entrarei em detalhes do comportamento do Transaction Log em cada modelo recuperao, pois
independente do modelo utilizado, o arquivo de log pode fragmentar.
Internamente, o log dividido em pequenos blocos chamados de Virtual Log Files (VLF).
Alm de ser a unidade de diviso do Transaction Log, o VLF permite o efeito circular do log atravs de sua
reutilizao.

M V T e c h | 257

SQL Server: Alm do Conceito


Blog Post Collection

O tamanho do VLF definido automaticamente variando de acordo com o crescimento do Log.


A Tabela abaixo, informa como ocorre a diviso (Fonte: Kimberly Tripp)

< 64MB = 4 VLFs


> 64MB < 1GB = 8 VLFs
> 1GB = 16 VLFs

Usando o exemplo de uma carga de dados que force um crescimento do arquivo de Log em 1000MB,
podemos ter:
Em um Growth de 10 MB => 4 VLFs de 2.5MB => Total de 400 VLFs.
Em um Growth de 200MB => 8 VLFs de 25MB => Total de 40 VLFs
Em um Growth de 1000MB => Total de 16 VLFs de 62.5MB
A partir do exemplo acima, fica claro que uma configurao ruim para o Auto Growth do arquivo de Log
gerar muitos VLFs, caracterizando o que chamamos de Fragmentao Interna do Transaction Log.
A fragmentao interna causa impactos em todos os processos que utilizam o Transaction Log e nas
aplicaes. (Sim... seus Updates e Inserts!!!)
Lembram que No incio do post, informei a configurao default de criao do banco de dados. Lembrase?

M V T e c h | 258

SQL Server: Alm do Conceito


Blog Post Collection
Tamanho Inicial = 1MB com Growth = 10%.
Imagina um arquivo de log de alguns "Gigas" utilizando a configurao default...Ahhh!
Para verificar as informaes de VLFs do arquivo de log, utilizamos o comando DBCC LOGINFO.
A quantidade de linhas retornadas justamente a quantidade de VLFs existentes no Database.
Abaixo, informaes das colunas retornadas pelo comando.

Destaque para as colunas:


FileSize - Tamanho do VLF em Bytes.
FSeqNo - Nmero que define a sequncia de utilizao dos VLFs.
Status - Em uso = 2, Livre = 0
CreateLSN - LSN no momento da criao dos VLFs. Quando igual a 0 (Zero) so VLFs criados no Create
Database.
Ok. J sabemos conceitualmente como o Transaction Log fica fragmentado e como analisar informaes
internas do arquivo de Log. Mas como resolver a fragmentao?
No prximo post, vamos colocar a mo na massa!
At o prximo post!

M V T e c h | 259

SQL Server: Alm do Conceito


Blog Post Collection

Fragmentao do Transaction Log - Parte II


No post anterior, abordei sobre o Transaction Log, como ocorre sua fragmentao e como podemos
identific-la.
Como prometido, neste post vamos verificar como resolver a fragmentao interna do Log.
Mos massa!
Para exemplificar, vou criar os Databases LargeVLF_Full, LargeVLF_Simple e SmallVLF com as seguintes
configuraes para os arquivos de Log:
LargeVLF_Full com Tamanho de 1MB e File Growth de 10% no recovery model FULL.
LargeVLF_Simple com Tamanho de 1MB e File Growth de 10% no recovery model SIMPLE.
SmallVLF com Tamanho de 8000MB e File Growth de 4000MB no recovery model FULL.

M V T e c h | 260

SQL Server: Alm do Conceito


Blog Post Collection

Aps criar os Databases, vamos analisar como esto os VLFs dos arquivos de log atravs do comando DBCC
LOGINFO.
LargeVLF_Full com 4 VLFs de "256Kb".
LargeVLF_Simple com 4 VLFs de "256Kb".
SmallVLF com 16 VLFs de 500MB.

M V T e c h | 261

SQL Server: Alm do Conceito


Blog Post Collection

Agora, vamos executar o script abaixo em todos os Databases.

M V T e c h | 262

SQL Server: Alm do Conceito


Blog Post Collection

Aps a criao da tabela e execuo dos inserts, vamos analisar como esto os arquivos de log de cada
Database.
O
Database
LargeVLF_Full
aumentou
de
4
VLFs
para
259
Observe que no modelo de recuperao Full, o status de todos os VLFs esto igual a 2 (Em uso).

M V T e c h | 263

VLFs.

SQL Server: Alm do Conceito


Blog Post Collection

D ICA :
Voc pode verificar o que est retendo o arquivo de log (status = 2) e impedindo a reutilizao dos VLFs
atravs
das
colunas
log_reuse_wait
e
log_reuse_wait_desc
na
sys.databases.
Neste caso, o Backup de Log!

M V T e c h | 264

SQL Server: Alm do Conceito


Blog Post Collection

As possveis causas de reteno podem ser encontradas neste link. (http://msdn.microsoft.com/enus/library/ms345414%28SQL.105%29.aspx)


O
Database
LargeVLF_Simple
aumentou
de
4
VLFs
para
91
Pela caracterstica do modelo de recuperao Simples, temos os status 0 (Livre) e 2 (Em uso).

VLFs.

No modelo Simple o log automaticamente truncado, mas isso no o impede de ficar fragmentado.
Cuidado!
Observe que o FileSize dos VLFs nos Databases LargeVLF_Full e LargeVLF_Simple so diferentes a cada
crescimento. Isto motivado pela configurao do File Growth em percentual.

M V T e c h | 265

SQL Server: Alm do Conceito


Blog Post Collection

O
Database
SmallVLF
continua
com
os
mesmos
Apenas o segundo e terceiro arquivo passaram a ser utilizados (Status = 2).

M V T e c h | 266

16

VLFs.

SQL Server: Alm do Conceito


Blog Post Collection

Podemos afirmar que os Databases LargeVLF_Full e LargeVLF_Simple esto fragmentados! (Utilizo como
"referncia" o valor mximo de 50 para quantidade de VLFs. Fonte: Kimberly Tripp)
E em relao aos impactos das operaes de Inserts e Updates mencionados no primeiro post por voc
Leandro?!
O arquivo de log no se beneficia do recurso Instant File Initialization. Quando necessrio o seu
crescimento, seus Updates e Inserts ficaro bloqueados at a concluso do crescimento do arquivo de
log.

V AMOS TESTAR !
Para este teste, vamos realizar um update em todos os registros da Tabela nos Databases LargeVLF_Full
e SmallVLF, medindo o tempo de execuo.

M V T e c h | 267

SQL Server: Alm do Conceito


Blog Post Collection

A diferena entre os Updates de 1896ms.


Para verificar o que motivou esta diferena, vamos ao Default trace Log (Se no estiver desabilitado!).

M V T e c h | 268

SQL Server: Alm do Conceito


Blog Post Collection

S para realizar o Auto Growth do arquivo de Log do Database LargeVLF_Full foram gastos 1486ms.
Dica: Evite crescimentos de arquivo do SQL Server durante o dia!
Bem, espero que tenha ficado claro!
Voltando para a resoluo do problema de fragmentao...
Para "arrumar" nosso arquivo de log, devemos realizar os seguintes procedimentos:
Backup de Log.
Shrink do arquivo de Log.
Alterao do File Size e Auto Growth para um tamanho apropriado.
Para facilitar minha vida, criei o script "Analise de Fragmentao" que ao ser executado realiza as
seguintes atividades:
Verifica e exibe os Databases que contenham mais de 50 VLFs.

M V T e c h | 269

SQL Server: Alm do Conceito


Blog Post Collection
Exibe o tamanho e o percentual de utilizao dos arquivos de log atravs do comando DBCC
SQLPERF(LOGSPACE).
Monta atravs de "Print", os comandos de ajustes para os Databases que apresentam mais de 50 VLFs.
Checkpoint.
Backup de Log se o modelo de recuperao no for Simple.
Shrink (Recuperando o nome lgico do arquivo)
Comando para alterar o File Size e File Growth (Recuperando o nome lgico do arquivo)

Abaixo o retorno da query.

M V T e c h | 270

SQL Server: Alm do Conceito


Blog Post Collection

Aps analisar o ambiente e copiar os comandos gerados para uma nova janela de query, informe:
File Size e File Growth para os arquivos de Log identificados no script.
Execute o script de ajustes em um momento propcio, ou seja, em uma janela de manuteno.
Execute novamente o script "Anlise de fragmentao" para verificar se seu ambiente est normalizado.
Fazer o download dos scripts aqui (http://sdrv.ms/YmYbLK)

I NFORMAO ADICIONAL

Ter poucos VLFs e de tamanho "considervel" tambm prejudicial ao seu ambiente, pois ir impactar na
liberao de espao do arquivo de Log. VLFs de no mximo 400/500MB o indicado.

M ELHORES PRTICAS :

M V T e c h | 271

SQL Server: Alm do Conceito


Blog Post Collection
Monitore seu ambiente.
Escolha o recovery model ideal para cada ambiente e necessidades de negcio.
Ajuste a frequncia de Backup de Log para controlar o tamanho do seu arquivo de Log.
No faa "BACKUP LOG ... WITH TRUNCATEONLY pois ele quebrar a sequncia do Backup de Log.
Utilize transaes curtas para que no retenha os VLFs por muito tempo.
Ajuste apropriadamente o File Size e File Growth do seu arquivo de Log.
Monitore seu ambiente.
E a pessoal, como est o seu ambiente...

Espero que o post ajude.


At o prximo!

M V T e c h | 272

SQL Server: Alm do Conceito


Blog Post Collection

Luciano Moreira
luticm.blogspot.com

O caso dos snapshots e data cache thrashing


Dia 30/06/2011 foi o ltimo dia do Luan Moreno na Sr. Nimbus e durante o almoo estvamos
conversando sobre o SQL Server (para variar um pouco), quando ele disse uma frase muito interessante
Quando voc l do snapshot o SQL Server faz a leitura direta no disco. Fiz uma cara de interrogao e
depois dele explicar melhor entendi o que ele quis dizer: quando voc tem um snapshot, as pginas do
banco de dados de origem no so compartilhadas com as do snapshot dentro do data cache.
Muito interessante! O Luan comentou que leu isso junto ao time do SQLCAT (referncia fina e confivel),
e esta pequena observao que pode passar despercebida me levou a escrever este artigo, onde podemos
ter um potencial problema de data cache thrashing.

DATA CACHE E O DATABASE SNAPSHOT.

Primeiramente vamos analisar o funcionamento do data cache no SQL Server quando utilizado o database
snapshot. Por simplicidade criamos uma tabela onde cada registro ocupa uma pgina e inserimos 20.000
pginas de dados (script 1).

S CRIPT 1 C RIAO DOS BANCOS DE DADOS

USE master
go
CREATE DATABASE DataCache
go
USE DataCache
go
CREATE TABLE Dados
(ID INT IDENTITY NOT NULL PRIMARY KEY,
Texto CHAR(8000) DEFAULT 'Sr. Nimbus')
GO
INSERT INTO Dados DEFAULT VALUES
GO 20000

M V T e c h | 273

SQL Server: Alm do Conceito


Blog Post Collection
CREATE DATABASE DataCache_Snapshot
ON (Name = 'DataCache',
filename = 'C:\temp\DataCache_Snapshotshot.mdf')
AS SNAPSHOT OF DataCache
GO

Quando o snapshot criado um arquivo de dados utilizado e aparentemente possui o mesmo tamanho
do original, mas somente as pginas que foram alteradas desde a criao do snapshot sero levadas para
o novo arquivo (sparse file), conforme a figura 01. Ento para o banco de dados DataCache_Snapshot um
mapa de bits criado em memria, para o SQL Server saber se deve ler uma pgina do arquivo original
ou do snapshot, indicando onde est a pgina correta para leitura.

(Figura 01 Sparse file)

Neste momento no tivemos alterao alguma, ento todas as pginas que precisamos para os dois
bancos esto no arquivo original, vamos ento executar um DBCC DROPCLEANBUFFERS para limpar o data
cache e executar os comandos abaixo. O que voc espera em termos de I/O?

SCRIPT 2 CUSTO DE IO PARA AS CONSULTAS

SET STATISTICS IO ON
DBCC DROPCLEANBUFFERS
GO
SELECT *
FROM DataCache.dbo.Dados
SELECT *
FROM DataCache_Snapshot.dbo.Dados
go
M V T e c h | 274

SQL Server: Alm do Conceito


Blog Post Collection

No primeiro select temos o esperado, uma srie de leituras fsicas (seja read-ahead ou no) colocando as
pginas de dados em cache. E a segunda consulta? J que no houve alteraes nos dados nenhuma das
pginas estar no novo arquivo, e como todas as pginas carregadas pelo primeiro SELECT esto em cache,
ento no necessrio ler nada do disco, correto?

S CRIPT 3 R ESULTADO DE IO PARA AS CONSULTAS


(20000 row(s) affected)
Table 'Dados'. Scan count 1, logical reads 20076, physical reads 51, read-ahead reads 20055, lob logical
reads 0, lob physical reads 0, lob read-ahead reads 0.

(20000 row(s) affected)


Table 'Dados'. Scan count 1, logical reads 20075, physical reads 50, read-ahead reads 20075, lob logical
reads 0, lob physical reads 0, lob read-ahead reads 0.

Na verdade no! O data cache referencia as pginas atravs da combinao: banco de dados, arquivo e
pgina (dbid, fileid, pageid). Quando procura por uma pgina do novo banco de dados que no est em
cache, resta a ele fazer uma leitura no disco, referenciando o mapa de bits para saber se deve ler a pgina
do arquivo original ou do novo.
Se as consultas forem executadas novamente no ser necessria nenhuma operao de I/O, pois as
pginas esto em cache. Consultando sys.dm_os_buffer_descriptors (script 4) veremos que temos uma
srie de pginas duplicadas, com diferena apenas no database_id (figura 2).

S CRIPT 4 C ONSULTANDO O DATA CA CHE

select *
from sys.databases
where name like '%datacache%'
go
select *
from sys.dm_os_buffer_descriptors
where
database_id
in
(DB_ID('DataCache'),
DB_ID('DataCache_Snapshot')) and file_id <> 2
order by page_id, database_id
go

M V T e c h | 275

SQL Server: Alm do Conceito


Blog Post Collection

Em termos Internals, o SQL Server no reusa a estrutura BUF entre pginas do snapshot e banco de dados,
ento as pginas ficaro duplicadas em cache, mesmo que no estejam presentes no arquivo de dados do
snapshot.

Figura 2 Pginas duplicadas em cache

DATA CACHE THRASHING

At agora foi apresentado o funcionamento do database snapshot em relao ao data cache, mas qual
o problema que me levou a escrever este artigo? Uma possvel presso no data cache por conta do SQL
Server no reutilizar as pginas entre snapshots!
Imagine um caso onde um DBA decide manter alguns snapshots do banco de dados (ex.: um snapshot por
dia) em um ambiente onde o volume de alteraes pequeno, ento o overhead da operao copy-onwrite no to significativo. Durante a semana os dados de uma tabela so comparados entre os dias em
que o snapshot tirado, sendo que isso acontece diversas vezes ao dia. Viu o potencial problema?
Vamos aos scripts, primeiro vamos definir o tamanho do buffer pool do SQL Server para 1GB e criar mais
alguns snapshots. Tendo a tabela 20.000 pginas aproximadamente, temos 8K * 20.000 pginas,
aproximadamente 160MB.

S CRIPT 5 C RIANDO DIVERSOS SNAP SHOTS E MAX SERVER MEMORY

SP_CONFIGURE 'MAX SERVER MEMORY', 1000


M V T e c h | 276

SQL Server: Alm do Conceito


Blog Post Collection
RECONFIGURE
SHUTDOWN
go
CREATE DATABASE DataCache_Snapshot2
ON (Name = 'DataCache',
filename = 'C:\temp\DataCache_Snapshotshot2.mdf')
AS SNAPSHOT OF DataCache
GO
CREATE DATABASE DataCache_Snapshot3
ON (Name = 'DataCache',
filename = 'C:\temp\DataCache_Snapshotshot3.mdf')
AS SNAPSHOT OF DataCache
GO
CREATE DATABASE DataCache_Snapshot4
ON (Name = 'DataCache',
filename = 'C:\temp\DataCache_Snapshotshot4.mdf')
AS SNAPSHOT OF DataCache
GO
CREATE DATABASE DataCache_Snapshot5
ON (Name = 'DataCache',
filename = 'C:\temp\DataCache_Snapshotshot5.mdf')
AS SNAPSHOT OF DataCache
GO

Com cinco snapshots criados, se executarmos uma consulta que obriga o SQL Server a varrer cada pgina
da tabela, ser colocado aproximadamente 960 MB no data cache (script 6). Como todas as pginas
couberam em memria aps a execuo dos seis primeiros SELECTs (sim, o I/O foi pesado), se eu executar
todas as consultas 10 vezes em seguida o tempo total de execuo ficar em torno de 4 segundos.

S CRIPT 6 U TILIZANDO O ESPAO D O DATA CACHE

DBCC DROPCLEANBUFFERS
go
SELECT count(*) FROM DataCache.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot2.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot3.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot4.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot5.dbo.Dados
go
SELECT count(*) FROM DataCache.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot2.dbo.Dados
M V T e c h | 277

SQL Server: Alm do Conceito


Blog Post Collection
SELECT count(*) FROM DataCache_Snapshot3.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot4.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot5.dbo.Dados
go 10
E se outro snapshot for criado e aumentarmos uma consulta no nosso batch? Com o limite de memria
definido para o SQL Server no ser possvel colocar mais 160MB em cache, restando ao SQL Server
comear a tirar as pginas do cache, forando operaes de I/O e claro, diminuindo a expectativa de vidas
das pginas em cache (script 7).

S CRIPT 7 D ATA C ACHE THRASHING

DBCC DROPCLEANBUFFERS
go
SELECT count(*) FROM DataCache.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot2.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot3.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot4.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot5.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot6.dbo.Dados
go
SELECT count(*) FROM DataCache.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot2.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot3.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot4.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot5.dbo.Dados
SELECT count(*) FROM DataCache_Snapshot6.dbo.Dados
go 10

O segundo loop que forou uma srie de operaes de I/O demorou entre 2:30 min e 3:00 min em minha
mquina, uma diferena considervel para os 4 segundos. Se voc quiser ver um comportamento
diferente, tente alterar a ordem das consultas, para que o SQL Server no favorea as pginas de alguns
bancos por conta do LRU-K.
Esse efeito eu chamo de data cache thrashing, pois similar a um memory thrashing em relao ao paging
file. Obviamente foi um exemplo estruturado para mostrar o overhead deste no SQL Server, mas pense
no impacto que isso pode causar no seu ambiente quando colocado em paralelo com outros bancos de
dados disputando um espao data cache. Se voc cria vrios snapshots com o objetivo de acelerar as suas
consultas (o que no justificvel), cuidado, voc pode ser pego de surpresa pelo caso dos snapshots e o
data cache thrashing.
Abraos e at um prximo artigo!

M V T e c h | 278

SQL Server: Alm do Conceito


Blog Post Collection

Trigger causando deadlocks


Na correria do dia eu recebi uma ligao de um DBA questionando-me sobre um problema de deadlock
e, mesmo com o dia atolado, eu separei uns minutinhos para ajud-lo. Bom, vamos ao problema:
Cenrio: O cliente possui um problema de deadlock em algumas tabelas e depois de adicionar alguns
ndices o problema deixou de acontecer. Mas o DBA (de forma bem perspicaz) ainda no est satisfeito
com o resultado e procurou minha ajuda para uma recomendao mais embasada.

P ERGUNTA : INDEXAO PODE ELIMI NAR PROBLEMAS DE DEADLOCKS ?


Resposta: quase isso! Uma indexao correta pode acelerar as consultas e operaes que estavam
entrando em deadlock, resultando em uma possibilidade menor da situao se repetir, ento uma
indexao correta pode sim DIMINUIR (no eliminar, talvez somente em um caso ou outro) os deadlocks!
uma abordagem que utilizamos quando estamos lidando com alguns deadlocks que so "by design", isto
, no podemos alterar o cdigo que causa o problema.

Segue um script que simula o problema original, foi bater o olho nele que eu j vi o deadlock, mas para
voc que quer praticar um pouco, coloque o script em um banco qualquer e mos obra!

USE Inside
go
IF OBJECT_ID('DeadlockTrigger') IS NOT NULL
DROP TABLE [DeadlockTrigger]
go
CREATE TABLE [dbo].[DeadlockTrigger](
[Codigo] [int] NOT NULL,
[Marca] [char](12) NULL,
[Numero] [char](12) NULL,
[Qtde] [decimal](10, 3) NULL,
[Numeracao] [int] NOT NULL
) ON [PRIMARY]
GO
ALTER
TABLE
[dbo].[DeadlockTrigger]
ADD
CONSTRAINT
[DF_DeadlockTrigger_Numeracao] DEFAULT (0) FOR [Numeracao]
GO
create
trigger
[dbo].[trgI_DeadlockTrigger]
[dbo].[DeadlockTrigger] for insert as
begin

M V T e c h | 279

on

SQL Server: Alm do Conceito


Blog Post Collection
update
DeadlockTrigger
set
Numeracao
=
(SELECT
MAX(Numeracao)+1 FROM DeadlockTrigger) WHERE Numeracao = (select
Numeracao from inserted WHERE Numeracao=0)
return
end
GO

Como vocs podem notar acima, a trigger responsvel por definir a numerao sequencial dos registros
na tabela, pegando o maior nmero atual da tabela.

E NTO PERGUNTO : AONDE EST O DEADLOC K ?

<!-- Se voc quiser analisar o problema e descobrir qual o deadlock, pare aqui e v
brincar com o SQL Server -->

E NCONTRANDO O DEADLOC K

Se utilizarmos o SSMS e executarmos um insert simples (script abaixo), o SQL Server vai inserir um registro
na tabela (lock X - exclusivo) e depois executar um select na tabela procurando pelo maior nmero
existente, que atualizar o registro corrente com esse valor. Essa busca um table scan e como a prpria
transao possui um bloqueio exclusivo no registro que foi inserido, a trigger funciona que uma beleza!
Veja parte dos planos nas figuras abaixo...

M V T e c h | 280

SQL Server: Alm do Conceito


Blog Post Collection
(Figura 01 Insert seguido do update da trigger)

(Figura 02 Plano do update fazendo alguns table scans)

Adicionando um pouco de concorrncia no nosso banco de dados, podemos ver o problema acontecendo,
para isso basta disparar o script abaixo em conexes diferentes e depois de alguns segundos vamos ver a
mensagem: Msg 1205, Level 13, State 45, Procedure trgI_DeadlockTrigger, Line 3 Transaction (Process
ID 52) was deadlocked on lock resources with another process and has been chosen as the deadlock
victim. Rerun the transaction.

WHILE 1=1
BEGIN
INSERT INTO DeadlockTrigger (Codigo, marca, numero, Qtde) VALUES
(1, 'Sr. Nimbus', '61 30102050', 300)
END

Quais foram os recursos que entraram em deadlock? Usando o profiler podemos capturar a seguinte
informao:

M V T e c h | 281

SQL Server: Alm do Conceito


Blog Post Collection

(Figura 03 deadlock S com X)

Analisando a sequncia das operaes fica evidente que o temos o cenrio onde a transao 1 insere um
registro e logo depois a transao 2 insere mais um registro. No momento em que a transao 1 volta a
executar a trigger e o update faz o select (table scan) a transao 1 fica bloqueada pelo lock exclusivo da
transao 2, quando a transao 2 entra para execuo ela fica bloqueada pelo lock exclusivo da transao
01. Como resultado temos um deadlock.

M INIMIZANDO OS DEADLO CKS

A maneira encontrada pelo cliente de minimizar o problema foi criar um ndice no campo Numeracao,
conforme o script abaixo:

CREATE
NONCLUSTERED
[dbo].[DeadlockTrigger]
(
[Numeracao] ASC
)
GO

INDEX

[idx_Numeracao]

ON

O que muda com esse ndice? Ao invs do update da trigger realizar um table scan, ele passa a fazer um
index seek no idx_Numeracao, ento como o registro inserido com numerao = 0 (constraint default),
ele estar em um ramo do ndice diferente do MAX(numeracao), permitindo que a consulta seja feita sem
problema de bloqueio entre S e X (visto na figura 03).
Ento estamos livres do problema? Aparentemente sim, mas basta executar novamente os loops
concorrentes que vemos a mesma mensagem 1205!
o mesmo deadlock? No! Se capturarmos o problema com o profiler veremos o seguinte:

M V T e c h | 282

SQL Server: Alm do Conceito


Blog Post Collection

(Figura 04 deadlock U com X)

O problema no est mais com o select MAX(numeracao) do update! Agora o problema est com a
atualizao dos registros que possuem numeracao = 0, pois em determinado momento podemos ter dois
registros com o valor zerado (de transaes diferentes) e enquanto o SQL Server est varrendo o ndice
procura do objeto (usando o lock de Update) ele vai encontrar um registro bloqueado por outra transao
e vice-versa.
Ento a criao do ndice nesse caso somente est mudando um pouco o tipo de deadlock que
encontramos, saindo de um X com S para um X com U. E potencialmente, com uma tabela grande, a
chance de encontrarmos um deadlock fazendo um table scan MUITO maior do que utilizando um index
seek.
Resultado: O cliente pode estar com a falsa impresso de que resolveu o problema de deadlock. O que
muito ruim, pois esse ir se tornar um erro intermitente, daqueles mais chatos de entender.
Outra abordagem que o pessoal poderia tentar, e vejo muito por a, seria tentar evitar o problema do
deadlock X com S utilizando uma hint de NOLOCK durante a busca do update, da seguinte forma:

ALTER
trigger
[dbo].[trgI_DeadlockTrigger]
on
[dbo].[DeadlockTrigger] for insert as
begin
update DeadlockTrigger
SET
Numeracao
=
(SELECT
MAX(Numeracao)+1
FROM
DeadlockTrigger with (nolock))
WHERE Numeracao = (select Numeracao from inserted WHERE
Numeracao=0)
return
end

Dessa forma realmente no veramos mais deadlocks S com X, mas cairamos novamente no problema do
deadlock X com U e provavelmente com uma freqncia maior que a primeira abordagem, pois sendo um
update menos eficiente a transao toda levaria mais tempo, aumentado a chance do problema ocorrer.
Concorda?
M V T e c h | 283

SQL Server: Alm do Conceito


Blog Post Collection

R ESOLVENDO O PROBLEMA ( DE VERDADE )


Por motivos de negcio ou at histricos normal vermos algumas solues que acabam deixando de
lado os recursos da ferramenta, que potencialmente so mais eficientes. No caso acima fica patente que
a utilizao de um campo IDENTITY resolveria o problema do cliente, basta criar a tabela com o script
abaixo (e sem a trigger, claro!) que o problema do deadlock vai embora.

IF OBJECT_ID('DeadlockTrigger') IS NOT NULL


DROP TABLE [DeadlockTrigger]
go
CREATE TABLE [dbo].[DeadlockTrigger](
[Codigo] [int] NOT NULL,
[Marca] [char](12) NULL,
[Numero] [char](12) NULL,
[Qtde] [decimal](10, 3) NULL,
[Numeracao] [int] IDENTITY(1,1) NOT NULL
) ON [PRIMARY]
GO

Caso a resoluo do problema ainda no seja suficiente para convencer o cliente, podemos ver o lado de
desempenho da soluo com a trigger. Aps inserir uma pequena massa de dados (13.000 registros) eu
executei um insert e mostro na figura 05 o plano de execuo:

M V T e c h | 284

SQL Server: Alm do Conceito


Blog Post Collection
(Figura 05 Plano de execuo do insert)

Note que aqui estou utilizando a verso inicial do problema (sem o ndice), onde um table scan pesa muito
no custo relativo de update no batch, isto , do custo total para se fazer o insert a trigger responsvel
por 95%.
E a soluo com ndice versus a soluo com o campo IDENTITY, qual ser mais barata? Para verificar a
resposta dessa questo eu criei o ndice idx_Numeracao na tabela e criei a tabela DeadlockTrigger2, que
possui um IDENTITY no campo Numeracao e nenhuma trigger. Veja o resultado na figura 06.

(Figura 06 custos relativos)

O insert no primeiro caso responsvel por 86% do custo total de batch, enquanto o custo do segundo
insert de 14%. Claramente podemos notar que a segunda abordagem mais eficiente que a primeira,
alm de resolver o problema de deadlock, ento porque no utiliz-la?

CONCLUSO

M V T e c h | 285

SQL Server: Alm do Conceito


Blog Post Collection
importante analisarmos com cuidado quando um problema foi efetivamente resolvido, pois paliativos
podem nos enganar e criar problemas ainda maiores para o futuro. Sempre que existe uma abordagem
de implementao da soluo utilizando recursos da prpria ferramenta, eu dou preferncia a eles, pois
existe uma boa probabilidade de e serem mais eficientes e livres de efeito colateral.

Espero ter ajudado.


Abraos

M V T e c h | 286

SQL Server: Alm do Conceito


Blog Post Collection

VARCHAR(MAX) vs. TEXT (Sintaxe?)


Como vocs j podem ter visto, ns na Nimbus gostamos de detalhes do SQL Server, quanto mais interno
(ou misterioso) mais divertido. Hoje mostro para vocs um pequeno aspecto relacionado aos tipos de
dados, que inclusive j encontramos em um cliente e um ajuste gerou um grande e positivo impacto no
desempenho do ambiente SQL Server.
A dvida: VARCHAR(MAX) e TEXT so sinnimos no SQL Server? Se voc olhar o que o tipo de dados pode
armazenar parecem ser idnticos, ento se s uma diferena de sintaxe tanto faz qual eu utilizo, mas
levando em conta que o TEXT est marcado como deprecated, e s trocar tudo por VARCHAR(MAX) e
correr para o abrao! Calma l campeo, vamos a um exemplo simples (rode o script 01)...

S CRIPT 01 D UAS TABELAS IDNTICAS , VARCHAR(MAX) E TEXT

USE tempdb
go
IF OBJECT_ID('dbo.TabelaTEXT', 'U') IS NOT NULL
DROP TABLE dbo.TabelaTEXT
GO
CREATE TABLE dbo.TabelaTEXT (
ID INT IDENTITY NOT NULL CONSTRAINT PK_TabelaTEXT PRIMARY
KEY
, Nome VARCHAR(100) NOT NULL DEFAULT ('Sr. Nimbus')
, DataRegistro DATETIME2 NOT NULL DEFAULT(SYSDATETIME())
, Texto TEXT NOT NULL DEFAULT (REPLICATE('A', 2000))
)
GO
IF OBJECT_ID('dbo.TabelaVARMAX', 'U') IS NOT NULL
DROP TABLE dbo.TabelaVARMAX
GO
CREATE TABLE dbo.TabelaVARMAX (
ID INT IDENTITY NOT NULL CONSTRAINT PK_TabelaVARMAX PRIMARY
KEY
, Nome VARCHAR(100) NOT NULL DEFAULT ('Sr. Nimbus')
, DataRegistro DATETIME2 NOT NULL DEFAULT(SYSDATETIME())
, Texto VARCHAR(MAX) NOT NULL DEFAULT (REPLICATE('A',
2000))
)
GO
INSERT INTO dbo.TabelaTEXT DEFAULT VALUES
INSERT INTO dbo.TabelaVARMAX DEFAULT VALUES
M V T e c h | 287

SQL Server: Alm do Conceito


Blog Post Collection
GO 10000
SELECT ID, Nome FROM dbo.TabelaTEXT
SELECT ID, Nome FROM dbo.TabelaVARMAX
go

Quando voc executar o script acima vai encontrar o plano esperado para as duas consultas, um clustered
index scan pegando os 10.000 registros. O que pode te pegar de surpresa o custo relativo, 2% contra
98% (figura 01). Isso mesmo, S essa pequena diferena. Utilizando o STATISTICS IO, vemos o motivo
dessa diferena:
Table 'TabelaTEXT'. Scan count 1, logical reads 68
Table 'TabelaVARMAX'. Scan count 1, logical reads 3348

(Figura 01 comparando os planos de execuo)

Mas qual o motivo dessa diferena? Quando voc utiliza o VARCHAR(MAX), caso o seu large object (LOB)
caiba dentro da pgina de dados de 8K (nesse casso os 2.000 bytes cabem), o SQL Server vai favorecer
essa opo, diferente do TEXT! Isso , se voc est consultando na maioria do tempo outras colunas que
no a sua LOB, o SQL Server est carregando para o data cache pginas com baixa quantidade de registros,
minimizando a eficincia do seu cache e consequentemente, o desempenho geral do SQL Server. Ento
existem diferenas e voc pode ver o detalhe com algumas DMVs.

M V T e c h | 288

SQL Server: Alm do Conceito


Blog Post Collection
S CRIPT 02 A NALISANDO AS UNIDADES DE ALOCAO

SELECT
OBJECT_NAME(object_id) AS ObjectName ,
AU.type ,
AU.type_desc ,
AU.container_id ,
AU.filegroup_id ,
AU.total_pages ,
AU.used_pages ,
AU.data_pages
FROM SYS.system_internals_allocation_units AS AU
INNER JOIN SYS.Partitions AS P
ON AU.Container_id = P.Partition_id
WHERE Object_ID IN (object_id('TabelaTEXT'),
object_id('TabelaVARMAX'))
ORDER BY object_id, type
go

(Figura 02 Comparando AllocUnits)

Na figura 02 podemos ver que a tabela com TEXT possui poucas pginas de dados (IN_ROW_DATA),
contendo em seus registros ponteiros para unidades LOB onde efetivamente os dados esto. J no
VARCHAR(MAX) as unidades de alocao de LOB_DATA no esto em uso, com used_pages igual a zero
(ROW_OVERFLOW pode ser ignorado para esse artigo).
Viu a diferena? Pequeno detalhe que pode impactar (e muito!) o seu ambiente. E agora voc pode estar
se perguntando, como eu altero esse modo de operao? Simplesmente executar um REBUILD do ndice
no vai fazer com que ele mude seu comportamento.

S CRIPT 03 SP _ TABLEOPTION PARA LARGE VALUES

-- SP_TABLEOPTION!!

M V T e c h | 289

SQL Server: Alm do Conceito


Blog Post Collection
EXEC sp_tableoption 'TabelaVARMAX', 'large value types out of
row', 1
go

-- rebuild
ALTER INDEX PK_TabelaVARMAX
ON dbo.TabelaVARMAX
REBUILD
go
SELECT
OBJECT_NAME(object_id) AS ObjectName ,
AU.type ,
AU.type_desc ,
AU.container_id ,
AU.filegroup_id ,
AU.total_pages ,
AU.used_pages ,
AU.data_pages
FROM SYS.system_internals_allocation_units AS AU
INNER JOIN SYS.Partitions AS P
ON AU.Container_id = P.Partition_id
WHERE Object_ID IN (object_id('TabelaTEXT'),
object_id('TabelaVARMAX'))
ORDER BY object_id, type
go

-- No?! Outra possibilidade...

UPDATE dbo.TabelaVARMAX
SET Texto = Texto
GO

-- E agora, 100%?

SELECT
OBJECT_NAME(object_id) AS ObjectName ,
AU.type ,
AU.type_desc ,
AU.container_id ,
AU.filegroup_id ,
AU.total_pages ,
AU.used_pages ,
AU.data_pages
M V T e c h | 290

SQL Server: Alm do Conceito


Blog Post Collection
FROM SYS.system_internals_allocation_units AS AU
INNER JOIN SYS.Partitions AS P
ON AU.Container_id = P.Partition_id
WHERE Object_ID IN (object_id('TabelaTEXT'),
object_id('TabelaVARMAX'))
ORDER BY object_id, type
go

-- A diferena dos custos se manteve?

SELECT ID, Nome FROM dbo.TabelaTEXT


SELECT ID, Nome FROM dbo.TabelaVARMAX
go

-- E o espao das pginas de dados do ndice cluster?

SELECT
OBJECT_NAME(object_id) AS ObjectName ,
AU.type ,
AU.type_desc ,
AU.container_id ,
AU.filegroup_id ,
AU.total_pages ,
AU.used_pages ,
AU.data_pages
FROM SYS.system_internals_allocation_units AS AU
INNER JOIN SYS.Partitions AS P
ON AU.Container_id = P.Partition_id
WHERE Object_ID IN (object_id('TabelaTEXT'),
object_id('TabelaVARMAX'))
ORDER BY object_id, type
go
-- Organizando a casa...
ALTER INDEX PK_TabelaVARMAX
ON dbo.TabelaVARMAX
REBUILD
go
SELECT
OBJECT_NAME(object_id) AS ObjectName ,
AU.type ,
AU.type_desc ,
AU.container_id ,
AU.filegroup_id ,
AU.total_pages ,
M V T e c h | 291

SQL Server: Alm do Conceito


Blog Post Collection
AU.used_pages ,
AU.data_pages
FROM SYS.system_internals_allocation_units AS AU
INNER JOIN SYS.Partitions AS P
ON AU.Container_id = P.Partition_id
WHERE Object_ID IN (object_id('TabelaTEXT'),
object_id('TabelaVARMAX'))
ORDER BY object_id, type
go
-- Agora sim...
SELECT ID, Nome FROM dbo.TabelaTEXT
SELECT ID, Nome FROM dbo.TabelaVARMAX
Go
-- Diferena ainda existe, mas gerencivel
SELECT
OBJECT_NAME(object_id) AS ObjectName
, AU.*
, P.*
FROM SYS.system_internals_allocation_units AS AU
INNER JOIN SYS.Partitions AS P
ON AU.Container_id = P.Partition_id
WHERE Object_ID IN (object_id('TabelaTEXT'),
object_id('TabelaVARMAX'))
ORDER BY object_id, type
go

O script acima mostra o uso do sp_tableoption com a opo large value types out of row, que definido
Segundo o BOL significa: 1 = varchar(max), nvarchar(max), varbinary(max), xml and large user-defined
type (UDT) columns in the table are stored out of row, with a 16-byte pointer to the root, exatamente o
que queremos.
Um aspecto curioso que me chamou a ateno quando estvamos resolvendo o caso do cliente, e que
voc vai poder notar no script completo que acompanha o artigo, que uma vez habilitada essa opo o
rebuild do ndice NO fez a organizao que eu esperava. Foi necessrio um UPDATE dummy da coluna
VARCHAR(MAX) em todos os registros para o SQL Server colocar efetivamente o ponteiro de 16 bytes para
o LOB nas sua devida unidade de alocao.
Mesmo assim voc vai notar que os custos do plano de execuo se mantiveram mesmo aps o UPDATE,
pois no houve nenhuma operao para organizar os registros no ndice cluster, ento a baixssima
densidade de registros por pginas se manteve, com uma gigante fragmentao interna. Com o UPDATE
+ REBUILD conseguimos o que queramos e os planos agora so bem compatveis! Ainda ficou uma
diferena entre o nmero total de pginas no ndice cluster, mas agora essa diferena pequena e
gerencivel, quem sabe no falamos sobre isso em outro post...

M V T e c h | 292

SQL Server: Alm do Conceito


Blog Post Collection

Nilton Pinheiro
www.mcdabrasil.com.br/

Trabalhando com datas e converses no SQL Server


Uma reclamao bastante comum de muitos desenvolvedores est na aparente dificuldade em se
trabalhar com datas e horas no SQL Server, mais especificamente quando usando os tipos de dados
datetime e smalldatetime. Eu digo aparente dificuldade, porque a grande verdade que para trabalhar
com data e hora no SQL Server, a primeira coisa a fazer entender como estes tipos de dados armazenam
seus dados. A partir do momento que voc entender como o SQL Server armazena e trata esses dados,
voc ver que trabalhar com datetime e smalldatetime bastante simples.
Ento, neste tpico veremos como esses tipos de dados se diferenciam um do outro, como eles
armazenam seus dados e como trabalhar com esses dados. Abordaremos tambm algumas funes
internas do SQL Server que simplificam muito o trabalho com estes tipos de dados.

O S TIPOS DE DADOS D ATE T IME E S MALL D ATE T IME

Estes so dois tipos de dados bastante utilizados no SQL Server para trabalhar com valores data e hora. A
diferena bsica entre os dois, est na quantidade de bytes utilizados para o armazenamento da
data/hora, o range de datas suportadas e suas precises.
Enquanto o DateTime usa 8 bytes para o armazenamento, o SmallDateTime usa apenas 4 bytes e por
essa razo que o DateTime consegue armazenar um range maior de datas e tambm possui uma maior
preciso que o SmallDateTime.
O DateTime armazena datas de 1 de Janeiro de 1753 at 31 de Dezembro de 9999 com uma preciso de
3.33 milissegundos ou 0.00333 segundos, sendo os valores arredondados para incrementos de .000, .003
ou .007 segundos, como mostrado na Tabela 1.

Datas de Exemplo
Arredondamento
01/01/2015 23:59:59.999
02/01/2015 00:00:00.000
01/01/2015 23:59:59.995, 01/01/2015 23:59:59.996,
01/01/2015 23:59:59.997
01/01/2015 23:59:59.997 ou 01/01/2015 23:59:59.998
01/01/2015 23:59:59.992, 01/01/2015 23:59:59.993,
01/01/2015 23:59:59.993
01/01/2015 23:59:59.994
01/01/2015 23:59:59.990 ou 01/01/2015 23:59:59.991
01/01/2015 23:59:59.990
Tabela 1. Exemplos de arredondamento com DataTime

M V T e c h | 293

SQL Server: Alm do Conceito


Blog Post Collection
Observe que os horrios com milissegundos entre .990 e .991 foram arredondados para .990. Os valores
entre .992 e .994 foram arredondados para .993 e os valores entre .995 e .998 foram arredondados para
.997
O SmallDateTime armazena datas de 1 de Janeiro de 1900 at 6 de Junho de 2079 com preciso de 1
minuto. Valores SmallDateTime com 29.998 segundos ou menos, so arredondados para o minuto
anterior, valores com 29.999, so arredondados para o minuto superior. Alguns exemplos podem ser
vistos na Tabela 2.

Exemplo
Arredondamento
2014-05-08 12:35:29.998
2014-05-08 12:35:00
2014-05-08 12:35:29.999
2014-05-08 12:36:00
Tabela 2. Exemplos de arredondamento com SmallDataTime

Um ponto importante para ter sempre em mente que tanto o DateTime quanto o SmallDateTime
representam a data e hora como um valor que igual ao nmero de dias decorridos desde a meia-noite
do dia 1 de Janeiro de 1900, conhecida como data base. No entanto, como descrito anteriormente, o
SmallDateTime somente pode representar datas a partir desta data base em diante. J o DateTime,
tambm pode representar datas que estejam antes de 1 de Janeiro de 1900 e para fazer isso, ele armazena
os valores como nmeros negativos.
Valores DateTime so armazenados internamente pelo SQL Server como sendo 2 inteiros de 4 bytes
(totalizando 8 bytes de armazenamento). Os primeiros quatro armazenam o nmero de dias decorridos
antes ou aps a data base. Os outros quatro armazenam a hora do dia representada como unidades de
0.00333 segundos aps a meia noite. J valores para SmallDateTime so armazenados como sendo 2
inteiros de 2 bytes (totalizando 4 bytes de armazenamento). Os primeiros dois armazenam o nmero de
dias decorridos desde 1 de Janeiro de 1900. Os outros dois armazenam o nmero de minutos desde a
meia noite.

E NTENDENDO O ARMAZENA MENTO DOS VALORES DA TA E HORA

Para entender como os valores data e hora so armazenados no SQL Server, divida o valor data e hora em
duas partes a saber: a parte inteira e a parte fracional.
A parte inteira representa o nmero de dias decorridos desde a data base. A parte fracional representa a
parte horas, decorridas desde a meia-noite da data base.
Para que voc possa entender melhor, imagine que estamos em 4 de Janeiro de 1900 ao meio-dia.
Internamente, o valor que representa essa data e hora armazenado como 3.5. Ou seja, o nmero inteiro
trs representa o nmero de dias decorridos desde a data base e a frao 0.5 representa a metade do dia
M V T e c h | 294

SQL Server: Alm do Conceito


Blog Post Collection
transcorrido desde a meia-noite. Para simular isso no SQL Server, basta executar a consulta a seguir no
SQL Server Management Studio:
SELECT CAST(CAST('1900-01-04 12:00' AS DateTime) AS Float)

No exemplo, utilizamos a funo CAST para converter a string 1900-01-04 12:00 para DateTime e depois
para Float. Como resultado temos o valor 3.5 do tipo Float representando ento a data.
Se usarmos o mesmo SELECT passando como string a data 2015-01-30 12:00, teremos como resultado o
valor 42031.5 onde 42032 representa o nmero de dias decorridos desde a data base e 0.5 a metade do
dia desde a meia noite.
Uma caracterstica destes dois tipos de dados que eles no podem armazenar datas sem hora e nem
hora sem data. Como consequncia, se voc armazenar uma data sem informar a parte hora, a parte que
representa a hora ser definida como 0.
Isso ser representado como meia-noite utilizando o formato 00:00:00 se estiver utilizando um campo do
tipo SmallDateTime ou 00:00:00.000 se estiver utilizando um campo DateTime. Similarmente, se voc
armazenar apenas a hora sem informar uma data, a parte que representa a data ser definida como 0.
Isso ser representado como 1 de Janeiro de 1900 para ambos os tipos de dados. Para entender melhor,
execute o cdigo a seguir no SQL Server Management Studio:

CREATE TABLE TB_DATAS (


Parte_Data DateTime,
Parte_Hora SmallDateTime)
GO
INSERT TB_DATAS VALUES ('2015-01-30','15:10')
INSERT TB_DATAS VALUES ('11:00','2015-01-30')
GO
SELECT * FROM TB_DATAS

O script cria a tabela TB_DATAS com as colunas Parte_Data (DateTime) e Parte_Hora (SmallDateTime) e
resultado de sua execuo pode ser visto na Figura 1. No primeiro INSERT, observe que para na coluna
Parte_Data informada apenas a parte referente data (a hora est como 00:00:00.000) e para a coluna
Parte_Hora, apenas a parte referente hora (a data est como 1900-01-01). No segundo INSERT feito o
processo inverso.

Figura 1. Salvando dados em colunas DateTime e SmallDateTime


M V T e c h | 295

SQL Server: Alm do Conceito


Blog Post Collection

Observe que para ambos os tipos de dados, para as datas informadas sem a parte hora o SQL Server
considerou a hora como sendo 0 ou meia-noite. J para as datas sem a parte data o SQL Server considerou
a data como sendo 1 de Janeiro de 1900. Ou seja, a data base.
importante notar que o mesmo acontece quando voc faz um SELECT em um campo data que usa estes
tipos de dados. Vejam o exemplo a seguir:

SELECT CAST('2015-01-30' AS DateTime) As Parte_Data,


CAST('10:00' AS DateTime) AS Parte_Hora
SELECT CAST('2015-01-30' AS SmallDateTime) AS Parte_Data,
CAST('10:00' AS SmallDateTime) AS Parte_Hora

O resultado mostrado na Figura 2.

Figura 2. Exemplo de Select em um campo Data

No exemplo, o primeiro SELECT utiliza a funo CAST para converter a string representando a data para o
tipo DateTime, enquanto o segundo converte para o tipo SmallDateTime.
Observe que o primeiro CAST passa uma data sem informar a parte hora (2015-01-30), ento o SQL Server
entende que a parte hora meia-noite ou 00:00:00.000. O segundo CAST informa apenas a parte hora
(10:00), ento o SQL Server entende que a data 1 de Janeiro de 1900.

T RABALHANDO COM A PAR TE DATA


Entendido como o SQL Server trata e armazena as datas para estes tipos de dados, vamos ver ento como
fazer pesquisas com datas no SQL Server. Para um melhor entendimento, considerem uma tabela de
pedidos com os registros apresentados na Figura 3.

M V T e c h | 296

SQL Server: Alm do Conceito


Blog Post Collection

Figura 3. Dados de exemplo da tabela de pedidos

O script para criao da tabela e populao dos dados de exemplo encontra-se na Listagem 1.

L ISTAGEM 1. S CRIPT PARA CRIAO E POPULAO DA TABELA DE PEDIDOS

CREATE TABLE TB_PEDIDO(


ID_Pedido int,
ID_Cliente VarChar(10),
Data_Pedido DateTime,
Data_Envio SmallDateTime)
GO
INSERT TB_PEDIDO
VALUES (1,'NILTON','2014-02-28 10:00:00.000','2014-02-28
16:20:00')
INSERT TB_PEDIDO
VALUES (2,'NILTON','2014-02-15 13:58:32.823','2014-02-16
00:00:00')
INSERT TB_PEDIDO
VALUES (3,'JORGE','2014-02-27 00:00:00.000','2014-02-27
16:00:00')
INSERT TB_PEDIDO
VALUES (4,'JORGE','2014-02-27 10:15:56.833','2014-02-28
00:00:00')
INSERT TB_PEDIDO
VALUES (5,'CARLOS','2014-08-10 00:00:00.000','2014-08-10
00:00:00')
INSERT TB_PEDIDO
VALUES (6,'CARLOS','2014-08-10 10:21:15.637','2014-08-10
17:20:00')

Uma pesquisa muito comum quando trabalhamos com data e hora pesquisar por registros de uma
determinada data independente da hora. Usando os dados da tabela de pedidos, um exemplo seria
pesquisar por todos os pedidos enviados no dia 10-08-2014.

M V T e c h | 297

SQL Server: Alm do Conceito


Blog Post Collection
Se a data na coluna estiver sendo armazenada com a parte hora sendo 0 (como no caso do registro 5),
no haver problemas pois como vemos, quando voc pesquisa por uma data sem informar a parte hora,
o SQL Server considera a hora como sendo 0 ou meia-noite. Dessa forma buscar por todos os registros
que contenham a data 10-08-2014 e a parte hora como 00:00:00.
No entanto, como podemos ver nos dados de exemplo, tanto a coluna Data_Pedido quanto a Data_Envio
so usadas de forma inconsistente, ou seja, as vezes a parte hora informada e as vezes no. Isso pode
indicar que o objetivo do desenvolvedor era armazenar somente a parte data, mas isso no foi forado
pela aplicao e acabou gerando registros com a parte hora diferente de 0.
A conseqncia disso que se voc disparar uma consulta querendo saber todos os pedidos com data de
envio igual a 10-08-2014 (sem informar a parte hora), o resultado obtido no ser o esperado.
O SELECT para a obteno desses registros seria:

SELECT * FROM TB_PEDIDO WHERE Data_Envio = '2014-08-10'

Ao executar, o resultado mostra somente o registro 5 quando o desejado seria retornar os registros 5 e 6.
Isso acontece porque como a parte hora no foi informada na pesquisa, o SQL Server pesquisar pela data
onde a parte hora seja 0. Uma vez que a hora para o registro 6 17:20:00, o mesmo no retornado.
Sendo assim, como podemos fazer para contornar esse problema? Se esse tipo de consulta for muito
utilizada por sua aplicao, a sugesto que voc passe a trabalhar com range de valores. Exemplo:

SELECT * FROM TB_PEDIDO


WHERE Data_Envio BETWEEN '2014-08-10'
AND '2014-08-10 23:59:59.997'

Lembre-se que a clusula BETWEEN obtm valores que esto entre o primeiro e o segundo valor
informado (tambm conhecidos como limites inferior e superior). Voc no pode definir o limite superior
como 2014-08-10. Se o fizer, novamente obter como retorno apenas o registro 5, pois o SQL Server
tratar a hora como sendo 0.
Observe que no exemplo, o limite superior foi definido como 2014-08-10 23:59:59.997. Com isso, o SQL
Server buscar por todos os registros entre 2014-08-10 00:00:00.000 e 2014-08-10 23:59:59.997,
pegando assim todo o range de horrio do dia 2014-08-10 e obtendo ento todos os registros deste dia.
Veja o resultado na Figura 4.

M V T e c h | 298

SQL Server: Alm do Conceito


Blog Post Collection

Figura 4. Dados corretamente retornados

Um outro caminho para obter o resultado esperado usando operadores de comparao >= (maior igual)
e < (menor), como demonstrado no cdigo:

SELECT * FROM TB_PEDIDO


WHERE Data_Envio >= '2014-08-10' AND
Data_Pedido < '2014-08-11'

Nesse caso o SQL Server interpretar as datas como 2014-08-10 00:00:00.000 e 2014-08-11
00:00:00.000. Como o filtro busca por registros com data de pedido menor que 2014-08-11
00:00:00.000, ento o SQL Server retornar apenas os registros do dia 10-08-2014 at o horrio de
23:59:59.997.

F UNES E C ONVERSES
Uma prtica comum de muitos desenvolvedores fazer uso de algumas funes internas do SQL Server
para simplificar o trabalho com datas e algumas das funes mais comuns esto listadas na Tabela 3.

Funo
DATEDIFF()

DATEPART()

DATEADD()

Descrio
Calcula o intervalo entre duas
datas. Sintaxe:
DATEDIFF
(datepart,
startdate, enddate )

Exemplo
-- Retorna o dia da data especificada
SELECT DATEDIFF(day, 2014-10-17, 2014-10-18)

Para datepart voc pode usar: Year, quarter, Month,


dayofyear, Day, Week, Hour, minute, second e millisecond.
Retorna partes especficas de -- Retorna o minuto da data especificada
uma data.
SELECT DATEPART(minute, 2014-10-18 15:22:56.567)
Sintaxe:
DATEPART (datepart, date)
Para datepart voc pode usar: Year, quarter, Month,
dayofyear, Day, Week, Hour, minute, second e millisecond.
Retorna uma nova data -- Adiciona 3 dias data especificada
baseado na adio de um SELECT DATEADD(day, 3, 2014-10-18 15:22:56.567)
intervalo para uma data
especificada.
Sintaxe: Para datepart voc pode usar: Year, quarter, Month,
DATEADD (datepart, number, dayofyear, Day, Week, Hour, minute, second e millisecond.
date)
M V T e c h | 299

SQL Server: Alm do Conceito


Blog Post Collection
DAY()

MONTH()

YEAR()

CAST()

CONVERT()

Retorna
um
inteiro
representando a parte dia de
uma data. Sintaxe: DAY (date)
Retorna
um
inteiro
representando a parte ms
de uma data. Sintaxe:
MONTH (date)
Retorna
um
inteiro
representando a parte ano de
uma
data.
Sintaxe:
YEAR(date)
Converte um tipo de dados
para outro. Sintaxe: CAST
(expression AS data_type)

-- Retorna o valor 18
SELECT DAY(2014-10-18 15:22:56.567)
-- Retorna o valor 10
SELECT MONTH(2014-10-18 15:22:56.567)

-- Retorna o valor 2014


SELECT YEAR(2014-10-18 15:22:56.567)

-- Converte a string data para o tipo de dados DateTime e


depois para Float, obtendo a data como um valor Float (3.5)

SELECT CAST(CAST(1900-01-04 12:00 AS datetime) AS


float)
Similar ao CAST. Sintaxe: -- Converte a string data para o tipo de dados DateTime e
CONVERT
(data_type depois para VarChar de 10 posies, obtendo apenas a
[(length)] , expression [style]) parte data no formato dd/mm/yyyy (04/01/1900).
SELECT CONVERT(VarChar(10), CAST(1900-01-04 12:00 AS
datetime), 103)
Existem vrias opes de style (opcional), mas os mais
utilizados so:
103: Retorna apenas a parte hora no formato dd/mm/yyyy,
108: Retorna apenas a parte hora no formato hh:mm:ss,
114: Retorna apenas a parte hora no formato
hh:mi:ss:mmm(24h)
* Para ver outros estilos consulte o Books Online do SQL
Server.
Tabela 3. Funes do SQL Server

Caso sua consulta seja utilizada com pouca frequncia, voc pode realmente fazer uso de algumas dessas
funes para simplificar o trabalho com as datas. No entanto, de uma forma geral esta no deve ser
considerada uma boa prtica. Isso porque embora a utilizao de funes permita obter os resultados de
forma relativamente simples, quando voc usa uma funo em uma condio de busca, voc acaba
matando o ndice da tabela caso um ndice exista sobre a coluna do tipo data. Ou seja, o SQL Server acaba
no usando o ndice para otimizar a pesquisa ou acaba fazendo um SCAN no ndice.
Usando ainda os dados de exemplos da tabela de pedidos (Figura 3), uma opo seria utilizar a funo
CONVERT para obter todos os registros com Data_Pedido igual a 10-08-2014.

M V T e c h | 300

SQL Server: Alm do Conceito


Blog Post Collection
SELECT * FROM TB_PEDIDO
WHERE CONVERT(VarChar(10),
Data_Pedido, 103) = '10/08/2014'

Neste exemplo a funo converte o campo Data_Pedido para um VarChar de 10 posies, pegando assim
apenas a parte data no formato dd/mm/yyyy e comparando com o valor 10/08/2014. Como resultado, o
SELECT retornar os registros 5 e 6, os mesmo retornados na Figura 4. Porm, ao verificar o plano de
execuo desta consulta (Figura 5) possvel ver claramente que o SQL Server executou um Index Scan
sobre o ndice existente para a coluna Data_Pedido.

Figura 5. Index Scan sendo executado sobre o ndice da coluna Data_Pedido

Observe ento na Figura 6 que isso j no acontece quando uma funo de converso no utilizada.
Podemos verificar isso com o script abaixo.

SELECT * FROM TB_PEDIDO


WHERE Data_Envio >= '2014-08-10' AND
Data_Pedido < '2014-08-11'

Figura 5. Index Seek sendo executado sobre o ndice da coluna Data_Pedido

M V T e c h | 301

SQL Server: Alm do Conceito


Blog Post Collection
Um outro exemplo para obter os mesmos resultados seria utilizar as funes MONTH e DAY e YEAR:

SELECT * FROM TB_PEDIDO


WHERE DAY(Data_Pedido)=10 AND
MONTH (Data_Pedido)=08 AND
YEAR (Data_Pedido)=2014

Novamente, embora o uso de funes seja uma soluo possvel, sua utilizao deve ser extremamente
evitada. Isso porque como vocs devem imaginar a funo ser chamada para cada registro da tabela,
matando ento o ndice da tabela e gerando um alto consumo dos recursos do servidor. Para uma tabela
com milhes de registros, essa prtica certamente resultar em possveis impactos na performance.
Minha sugesto que procurem utilizar a soluo com o BETWEEN ou os operadores de comparao >=
(maior igual que) e < (menor que)

T RABALHANDO COM A PAR TE HORA


Realizar uma consulta que busque por uma hora especfica semelhante a realizar uma consulta que
busque apenas por uma data (sem a hora). Se a coluna armazenar apenas a parte referente a hora, a
busca pela hora ser simples.
No entanto, diferente dos valores data, o valor referente a hora representado por um valor numrico
aproximado. Podemos ver isso facilmente ao executarmos a seguinte instruo, onde o valor retornado
ser 0,983321759259259:

SELECT CAST(CAST('23:35:59' AS DateTime) AS Float)

Para ilustrar a pesquisa apenas pela hora, considerem uma tabela de apontamento de horas com os
registros apresentados na Figura 6.

Figura 6. Dados de exemplo da tabela de apontamento de horas

M V T e c h | 302

SQL Server: Alm do Conceito


Blog Post Collection

O script para criao da tabela e populao dos dados de exemplo encontra-se na Listagem 2.

Listagem 2. Script para criao e populao da tabela de apontamento de horas

CREATE TABLE TB_HORA (ID int,


Funcionario VarChar(10),
Data SmallDateTime,
Hora_Entrada DateTime,
Hora_Saida DateTime)
INSERT
VALUES
INSERT
VALUES
INSERT
VALUES
INSERT
VALUES
INSERT
VALUES
INSERT
VALUES

INTO TB_HORA
(1, 'NILTON','2014-10-10','08:30:00','12:30:15')
INTO TB_HORA
(2, 'NILTON','2014-10-10','13:32:00','17:38')
INTO TB_HORA
(3, 'CARLOS','2014-10-11','2014-10-11 08:30','12:30')
INTO TB_HORA
(4, 'CARLOS','2014-10-11','2014-10-11 13:30','17:30')
INTO TB_HORA
(5, 'CARLOS','2014-10-12','08:30:01.997','12:30')
INTO TB_HORA
(6, 'CARLOS','2014-10-12','13:30','17:30')

Aqui a coluna Hora_Entrada utilizada de forma inconsistente, ou seja, algumas vezes armazenando
somente a hora (a parte data definida como 1 de Janeiro de 1900), outras vezes armazenando a data e
a hora (registros 3 e 4).
Com isso, se voc utilizar a consulta a seguir para obter apenas os registros com hora de entrada igual a
08:30, voc ter como resultado apenas o registro de ID 1:

SELECT * FROM TB_HORA WHERE Hora_Entrada = '08:30'

O registro de ID 3 no retornado porque quando se pesquisa apenas pela hora o SQL Server entende
que a parte referente data deve ser 1900-01-01 (zero), o que equivale data base. Por outro lado, o
registro de ID 5 no retornado porque embora o valor esteja bastante prximo, o mesmo no 08:30.
Com a execuo do cdigo a seguir possvel ver como o SQL Server entende esses dois horrios em
formato numrico:

M V T e c h | 303

SQL Server: Alm do Conceito


Blog Post Collection
SELECT CAST(CAST('08:30' AS DateTime) AS Float),
CAST(CAST('08:30:01.997' AS DateTime) AS Float)

Caso execute o cdigo acima voc notar que a hora 08:30 entendida pelo SQL Server como o valor
numrico 0,354166666666667, enquanto que a hora 08:30:01.997 entendida como
0,354189776234568. Ou seja, realmente so bem diferentes.
Nesses casos, para ignorar a parte data de uma coluna DateTime ou SmallDateTime, voc pode utilizar a
funo CONVERT para separar o valor hora de seu componente data:

SELECT * FROM TB_HORA


WHERE CONVERT (VarChar(5),Hora_Entrada, 108) = '08:30'

Conforme apresentado na Figura 7, o SELECT retorna os registros 1, 3 e 5.

Figura 7. Resultado do SELECT usando a funo de converso para o campo hora

Se a parte hora for armazenada de forma inconsistente, ento voc tambm poder considerar a
realizao de pesquisas por range de valores hora. A seguinte instruo tambm retorna os registros 1, 3
e 5:

SELECT * FROM TB_HORA


WHERE CONVERT (VarChar(5),
Hora_Entrada, 108) >= '08:20' AND
CONVERT (VarChar(5), Hora_Entrada, 108) <='08:40'

Infelizmente, para obter a parte hora no existe uma maneira de obter esse resultado sem usar uma ou
mais funes, mas como dito anteriormente, por razes de performance evite a utilizao de funes em
campos utilizados em busca.
Se a parte hora for armazenada de forma consistente, ou seja, sem a parte referente a data, como o
caso da coluna Hora_Saida. Voc poder evitar a utilizao de funes fazendo uso de consultas como as

M V T e c h | 304

SQL Server: Alm do Conceito


Blog Post Collection
apresentadas abaixo. Mas lembre que neste caso ser retornado apenas os registros onde a parte data
1900-01-01.

SELECT * FROM TB_HORA


WHERE Hora_Saida BETWEEN '17:30' AND '17:40'
SELECT * FROM TB_HORA
WHERE Hora_Saida >= '17:30' AND Hora_Saida <='17:40'

Nestes exemplos, ambas as consultas retornam os registros 2, 4 e 6. Um outro caminho para trabalhar
mais facilmente com valores hora usar o data type SmallDateTime no lugar do DateTime.
Uma vez que o SmallDateTime sempre arredonda a parte hora para o minuto mais prximo (acima ou
abaixo), as horas que estiverem entre 08:59:29.999 e 09:00:29.998 sero armazenadas como 09:00. Se
esse tipo de arredondamento for possvel para sua aplicao, ento o uso do SmallDateTime evitar a
necessidade de buscas por range de valores hora.

CONCLUSO

Como vimos no decorrer deste artigo, o trabalho com data no SQL Server relativamente simples quando
entendemos como o servidor armazena e trata os valores. Um dos primeiros pontos a saber quando
trabalhamos com data se realmente precisar de uma preciso de milissegundos.
Com isso voc j decidir entre o tipo de dados DateTime ou SmallDateTime. Lembre-se que o DateTime
ocupa mais espao (8 bytes) que o SmallDateTime (4 bytes) e quando seu objetivo tratar apenas a parte
hora, pode lhe obrigar a trabalhar com ranges de valores hora.
O segundo ponto sempre garantir a consistncia dos valores, ou seja, quando o importante a parte
data tente manter a parte hora sempre como 0, quando o importante for a parte hora, tente manter a
parte data sempre como 1 de Janeiro de 1900. Com certeza esses cuidados simplificaro muito seu
trabalho com valores data e hora.

Um abrao e at a prxima.

M V T e c h | 305

SQL Server: Alm do Conceito


Blog Post Collection

Monitorando alteraes de Dados com a Clusula OUTPUT


Uma necessidade bastante comum em um ambiente SQL Server est em monitorar as operaes DML
executadas sobre uma tabela. A partir dpo SQL Server 2008 isso pode facilmente ser alcanado com o uso
do CDC (Change Date Capture). No entanto, isso tambm pode ser facilmente alcanado usando a clusula
OUTPUT.
Ento, para demonstrar a utilizao da clusula OUTPUT, usaremos como exemplo a tabela
CartaoDeCredito que pode ser criada em qualquer banco de dados utilizando o script da Listagem 1. O
script cria a tabela e a popula com dois regsitros e em nosso exemplo, esta ser a tabela a ser auditada. A
auditoria tem como objetivo monitorar os usurios que fizeram alteraes nos nmeros dos cartes de
crtido.

CREATE TABLE dbo.CartaoDeCredito (


[CreditCardID] [int] IDENTITY(1,1) NOT NULL,
[CardType] [nvarchar](50) NOT NULL,
[CardNumber] [nvarchar](25) NOT NULL,
[ExpMonth] [tinyint] NOT NULL,
[ExpYear] [smallint] NOT NULL,
[ModifiedDate] [datetime] NOT NULL
CONSTRAINT [DF_ModifiedDate] DEFAULT (getdate()),
CONSTRAINT [PK_CreditCardID] PRIMARY KEY CLUSTERED
([CreditCardID] ASC))
GO
INSERT dbo.CartaoDeCredito
(CardType,CardNumber,ExpMonth,ExpYear,ModifiedDate)
VALUES ('Visa','11111111111111',12,2014,'20090305'),
('MasterCard','22222222222222',12,2020,'20150105')
Listagem 1: Script para criao da tabela CartaoDeCredito

Conhecendo os objetivos e a estrutura da tabela a ser auditada, preciso ento ter uma segunda tabela
que ser usada para armazenar os dados da auditoria, chamaremos aqui de "tabela espelho". Uma
observao muito importante sobre esta tabela que para receber as linhas da clusula OUTPUT ela no
pode possuir triggers, check contraints ou qualquer foreign key referenciando suas colunas ou colunas de
outras tabelas.
Ento, com o script apresentado na Listagem 2 possvel criar a tabela que armazenar os dados
auditados durante as operaes de INSERT, UPDATE e DELETE sobre a tabela CartaoDeCredito. Notem
que esta tabela possui duas entradas para cada coluna da tabela a ser auditada. A coluna com o prefixo
INSERT armazenar os dados inseridos e a coluna com o prefixo DELETE os dados excludos. Outro ponto
a ser observado so as duas ltimas colunas do script (INSERT_Usuario e DELETE_Usuario). Estas colunas
existem apenas na tabela espelho e sero utilizadas para guardar a informao referente ao nome do

M V T e c h | 306

SQL Server: Alm do Conceito


Blog Post Collection
usurio que modificou o registro na tabela CartaoDeCredito. Para obter esta informao ser usada a
funo de sistema SUSER_SNAME() que retorna o nome do usurio que executou a operao.
CREATE TABLE dbo.CartaoDeCredito_Espelho (
AuditoriaID int IDENTITY(1,1) NOT NULL PRIMARY KEY,
ComandoDML varchar(10),
INSERT_CreditCardID int NULL,
DELETE_CreditCardID int NULL,
INSERT_CardType [nvarchar](50) NULL,
DELETE_CardType [nvarchar](50) NULL,
INSERT_CardNumber [nvarchar](25) NULL,
DELETE_CardNumber [nvarchar](25) NULL,
INSERT_ExpMonth [tinyint] NULL,
DELETE_ExpMonth [tinyint] NULL,
INSERT_ExpYear [smallint] NULL,
DELETE_ExpYear [smallint] NULL,
INSERT_ModifiedDate [datetime] NULL,
DELETE_ModifiedDate [datetime] NULL,
INSERT_Usuario varchar(50) NULL DEFAULT SUSER_SNAME(),
DELETE_Usuario varchar(50) NULL DEFAULT SUSER_SNAME()
)
Listagem 2: Script para criao da tabela CartaoDeCredito_Espelho

Agora que voc conhece a estrutura da tabela espelho, com o script da Listagem 3 possvel executar um
INSERT sobre a tabela CartaoDeCredito para popul-la com um registro.
-- INSERT
INSERT dbo.CartaoDeCredito
(CardType,CardNumber,ExpMonth,ExpYear,ModifiedDate)
-- Incio bloco OUTPUT
OUTPUT 'INSERT',
Inserted.CreditCardID,
Inserted.CardType,
Inserted.CardNumber,
Inserted.ExpMonth,
Inserted.ExpYear,
Inserted.ModifiedDate
INTO dbo.CartaoDeCredito_Espelho
(ComandoDML,INSERT_CreditCardID,INSERT_CardType,INSERT_CardNumber
,INSERT_ExpMonth,INSERT_ExpYear,INSERT_ModifiedDate)
-- Fim bloco OUTPUT
VALUES ('Amex','33333333333333',12,2020,'20150105')
Listagem 3: Script para carregar a tabela CartaoDeCredito

Note que a clusula OUTPUT esta posicionada entre as palavras chaves INSERT e VALUES (em negrito na
Listagem 3). Em verdade, observando atentamente possvel notar que a instruo de INSERT muito
semelhante a uma instruo de INSERT qualquer, a grande diferena no uso da clusula OUTPUT est no
M V T e c h | 307

SQL Server: Alm do Conceito


Blog Post Collection
fato de ter que acrescentar o cdigo destacado entre os comentrios Incio bloco OUTPUT e Fim bloco
OUTPUT). Tirando este bloco, a instruo de INSERT ficaria como abaixo:

INSERT dbo.CartaoDeCredito
(CardType,CardNumber,ExpMonth,ExpYear,ModifiedDate)
VALUES ('Amex','33333333333333',12,2020,'20150105')

Outro ponto importante, notem na Listagem 3 que aps o INTO dbo.CartaoDeCredito_Espelho tem-se
ento a lista das colunas da tabela CartaoDeCredito_Espelho onde os dados devem ser inseridos. Como a
operao de INSERT utiliza apenas a tabela virtual INSERTED, a lista de colunas possui apenas as colunas
correspondentes.
Assim como uma trigger de INSERT, a clusula OUTPUT tambm faz uso da tabela virtual INSERTED para
obter os dados afetados pela operao DML de INSERT. Quando usamos uma trigger, esta faz uso de duas
tabelas chamadas INSERTED e DELETED. Estas tabelas so tabelas virtuais que existem apenas durante o
tempo de execuo da trigger e podem ser usadas para capturar o antes e depois de uma operao DML.
As tabelas so afetadas de forma diferente dependendo da operao DML executada. Na Tabela 1 temos
o que contm em cada tabela de acordo com a operao DML.

Operao

Tabela INSERTED contm

Tabela DELETED contm

DELETE

No possui registros

Registros excludos

INSERT

Novos registros

No possui registros

UPDATE

Novos registros

Registros antigos

A clusula OUTPUT faz uso destas mesmas tabelas virtuais, ento quando voc executa um INSERT a
tabela virtual INSERTED possui o dados inseridos na tabela auditada, e a clusula OUTPUT utiliza a tabela
virtual para capturar os dados e inser-los na tabela CartaoDeCredito_Espelho.
O resultado da operao de INSERT executada sobre a tabela CartaoDeCredito com o script da Listagem
3 pode ser visto na Figura 1. Resultado da execuo do script abaixo.

SELECT TOP 5 * FROM dbo.CartaoDeCredito ORDER BY ModifiedDate


DESC
GO
SELECT
ComandoDML,INSERT_CreditCardID,INSERT_CardType,INSERT_CardNumber,
INSERT_ExpMonth,
INSERT_ExpYear, INSERT_ModifiedDate, INSERT_Usuario
FROM dbo.CartaoDeCredito_Espelho
M V T e c h | 308

SQL Server: Alm do Conceito


Blog Post Collection

Observe que o novo registro foi inserido sobre a tabela Sales.CartaoDeCredito e ao mesmo tempo um
registro tambm foi inserido sobre a tabela Sales.CartaoDeCredito_Espelho indicando ainda o usurio
que executou a operao.

Figura 1: Resultado de uma operao de INSERT sobre a tabela CartaoDeCredito

Para uma operao de UPDATE, o que muda que deve-se pegar os dados no apenas da tabela
INSERTED, mas tambm os da tabela DELETED. Isso porque quando ocorre uma operao de UPDATE o
que ocorre na prtica a excluso do dados antigos e a incluso dos novos dados sendo inseridos. Com
isso, durante uma operao de UPDATE a tabela INSERTED armazena os novos dados e a tabela DELETED
armazena os dados antigos ou excludos.
Observando o script da Listagem 4 voc notar que na lista de colunas passadas para a clusula OUTPUT
usado no apenas a tabela INSERTED, mas tambm a DELETED (bloco do OUTPUT). Bem como, aps o
INTO dbo.CartaoDeCredito_Espelho informado no apenas as colunas de prefixo INSERT, mas tambm
as de prefixo DELETE.

-- UPDATE
UPDATE dbo.CartaoDeCredito
SET CardNumber= '11111111112015'
OUTPUT 'UPDATE',
Inserted.CreditCardID,
Deleted.CreditCardID,
Inserted.CardType,
Deleted.CardType,
Inserted.CardNumber,
Deleted.CardNumber,
Inserted.ExpMonth,
Deleted.ExpMonth,
Inserted.ExpYear,
Deleted.ExpYear,
Inserted.ModifiedDate,
Deleted.ModifiedDate
INTO dbo.CartaoDeCredito_Espelho
(ComandoDML,INSERT_CreditCardID,DELETE_CreditCardID,INSERT_CardTy
pe,DELETE_CardType,
INSERT_CardNumber,DELETE_CardNumber,INSERT_ExpMonth,DELETE_ExpMon
th,INSERT_ExpYear,DELETE_ExpYear,
INSERT_ModifiedDate,DELETE_ModifiedDate)
WHERE CreditCardID=3
Listagem 4: Script para executar um UPDATE sobre a tabela CartaoDeCredito

M V T e c h | 309

SQL Server: Alm do Conceito


Blog Post Collection
O resultado da operao de UPDATE pode ser visto na Figura 2. Note que na tabela CartaoDeCredito o
nmero do carto de crdito para o CreditCardID 3 foi alterado de 33333333333333 para
11111111112015. Na tabela de auditoria CartaoDeCredito_Espelho podemos notar que tanto as colunas
de prefixo INSERT quanto as colunas de prefixo DELETE foram preenchidas. Na coluna DELETE_CreditCrad
temos ento o nmero antes da alterao e na coluna INSERT_CredtCard o novo nmero do carto de
crdito.

O resultado obtido ao executar o script abaixo:

SELECT TOP 5 * FROM dbo.CartaoDeCredito ORDER BY ModifiedDate DESC


SELECT
ComandoDML,INSERT_CreditCardID,INSERT_CardType,
INSERT_CardNumber,INSERT_ExpMonth,INSERT_ExpYear,
INSERT_ModifiedDate, INSERT_Usuario
FROM dbo.CartaoDeCredito_Espelho
SELECT
ComandoDML,DELETE_CreditCardID,DELETE_CardType,
DELETE_CardNumber,DELETE_ExpMonth,DELETE_ExpYear,
DELETE_ModifiedDate, DELETE_Usuario
FROM dbo.CartaoDeCredito_Espelho
Figura 2: Resultado de uma operao de UPDATE sobre a tabela CartaoDeCredito

Para finalizar, um exemplo demonstrando o uso da clusula OUTPUT em uma operao de DELETE. Como
voc j deve ter notado, para uma operao de DELETE apenas as colunas com prefixo DELETE para a
tabela CartaoDeCredito_Espelho sero preenchidas. O script para a operao de DELETE pode ser visto na
Listagem 5 e o exemplo exclui o registro de CreditCardID 3 da tabela dbo.CartaoDeCredito

-- DELETE
DELETE FROM dbo.CartaoDeCredito
OUTPUT 'DELETE',
Deleted.CreditCardID,
Deleted.CardType,
Deleted.CardNumber,
Deleted.ExpMonth,
Deleted.ExpYear,
Deleted.ModifiedDate
INTO dbo.CartaoDeCredito_Espelho
(ComandoDML,DELETE_CreditCardID,DELETE_CardType,
DELETE_CardNumber,DELETE_ExpMonth,DELETE_ExpYear,
DELETE_ModifiedDate)
WHERE CreditCardID=3
Listagem 5: Script para executar um DELETE sobre a tabela CartaoDeCredito

M V T e c h | 310

SQL Server: Alm do Conceito


Blog Post Collection
Podemos ver o resultado da operao na Figura 3. Note que o registro de CreditCardID 3 foi excludo da
tabela principal CartaoDeCredito. Para a tabela CartaoDeCredito_Espelho podemos notar tambm que as
colunas de prefixo INSERT esto como NULL e isso ocorre porque para as operaes de DELETE no h
insero de novos dados. J para as colunas de prefixo DELETE, temos o registro dos dados excludos e
quem o excluiu.

Figura 3: Resultado de uma operao de DELETE sobre a tabela CartaoDeCredito

D ICAS PARA A UTILIZA O DO OUTPUT


Como vocs devem ter notado, a clusula OUTPUT pode ser utilizada nas instrues Transact-SQL de
INSERT, UPDATE ou DELETE. Isso proporciona uma excelente flexibilidade, pois podemos utiliz-la apenas
nas instrues que desejamos monitorar. Desta forma, qualquer processo que tenha permisso para
modificar uma tabela pode usar a clusula OUTPUT para popular a tabela de auditoria. Algumas boas
prticas para a utilizao da clusula OUTPUT so as seguintes:

1) Remover qualquer permisso de acesso direto tabela auditada;


2) Escrever todas as operaes de INSERT, UPDATE e DELETE dentro de stored procedures;
3) Atribuir as permisses apenas nas stored procedures;

Seguir estas boas prticas garantir que o usurio s conseguir executar as operaes atravs das stored
procedures e consequentemente no executar nenhuma operao sem passar pela auditoria. O ponto
de ateno ao trabalhar com a clusula OUTPUT est em ficar sempre atento para no esquecer e fazer
as devidas modificaes nas procedures quando houver mudanas na estrutura da tabela auditada ou at
mesmo no esquecer da clusula OUTPUT quando estiver escrevendo novas procedures. Para evitar estes
problemas, minha sugesto que sejam criadas regras que definam os passos envolvidos para a
modificao ou criao de operaes que envolvam tabelas que precisem ser auditadas.
verdade que ao invz de trabalhar com a clusula OUTPUT voc tambm poderia executar esta auditoria
usando triggers sobre a tabela a ser auditada. No entando, quando trabalhamos com triggers, alm de
termos os problemas de overhead sobre as tabelas afetas ainda temos que nos preocupar em lembrar
das trigger sempre que modificamos as tabelas ou geramos scripts de criao das tabelas. Este problema
no existe com a utilizao da clusula OUTPUT pois tudo est dentro das prprias stored procedures que
executam as operaes de INSERT, UPDATE e DELETE. Se voc alterar a tabela auditada, certamente ter
que alterar tambm as procedures que executam estas operaes e neste momento ver a clusula
OUTPUT. Se voc gerar script de criao das tabelas, muito possivelmente ir gerar tambm os scripts de
criao das stored procedures e mais uma vez estar l a clusula OUTPUT.

M V T e c h | 311

SQL Server: Alm do Conceito


Blog Post Collection
Abraos

Nilton Pinheiro

M V T e c h | 312

SQL Server: Alm do Conceito


Blog Post Collection

Tiago Balabuch
www.tiagobalabuch.com

PERFORMANCE COUNTER - SUBSISTEMA DE DISCOS


Os administradores de storages esto constantemente tentando maximizar o desempenho de acesso ao
disco e problemas podem ser o resultado de qualquer coisa a partir de um componente configurado
incorretamente at um volume de carga extremamente grande. E aqui entra, na minha viso, a briga
entre o DBA e o Administrator de Storage mas essa uma histria longa. Voltando ao assunto, os bancos
de dados esto armazenados em discos (ou pelo menos at a chegada do SQL Server 2014, o recurso de
IN-Memory OLT, conhecido tambm por HEKATON, passa a armazenas dados em memria) que ao
contrrio da memria RAM, so mdias no-volteis.

U TILIZAO DE D ISCO
A utilizao do recurso de disco pode ser medida atravs de:
Operaes de I/O por segundo (IOPS) Nmero de operaes realizadas por segundo
Taxa de Transferncia (Throughput) Quantidade de dados (em Megabytes) transferidos

O S CONTADORES UTILIZADOS PARA MEDIR AS IN FORMAES SO :


Logical Disk: Disk Reads/sec e Disk Write/sec So respectivamente ao nmero de operaes de leitura
e escrita realizadas no volume ou disco. Valores abaixo de 100 IOPS so considerados baixos.
Logical Disk: Avg. Disk Read Bytes/Sec e Avg. Disk Write Bytes/Sec Taxas de transferncia para escrita e
leitura no subsistema de disco. Valores abaixo de 20MB so considerados baixos.

M V T e c h | 313

SQL Server: Alm do Conceito


Blog Post Collection
Grfico 1 Total de IOPS
O grfico 1 mostra o consumo de IO do subsistema de disco, onde a utilizao mxima chega perto dos
20 mil IOPS. Tambm possvel notar que a maior concentrao na utilizao do subsistema de disco para
leitura, visto que a gravao de dados consome pouco recurso.

Figura 2 Total de Throughput

T EMPO DE R ESPOSTA
Podemos definir latncia ou tempo de resposta como: uma medida de delay (tempo de atraso) desde o
momento de uma requisio de IO criado, at ao momento em que a requisio de IO completada.
Atravs de indicadores abaixo possvel dimensionar o impacto da utilizao do subsistema de disco.
Logical Disk: Avg. Disk sec/Read e Avg. Disk sec/Write o tempo mdio gasto em leitura e escrita de
uma operao de I/O no disco. Esse indicador corresponde ao tempo de resposta do disco, sendo
recomendado valores inferiores a 0.020 equivalente a 20 milissegundos.
Logical Disk: Current Disk Queue Lenght Informa a fila de cada volume ou disco. O valor ideal da fila de
disco zero, porm, existe uma tolerncia de at 2 operaes de I/O por disco fsico.

M V T e c h | 314

SQL Server: Alm do Conceito


Blog Post Collection

Grfico 3 Tempo de Resposta

O grfico 3 mostra que a fila de disco est alta porm o tempo de resposta do subsistema de disco no
ultrapassa 8 milissegundos ou 0.08. Nesse caso o enfileiramento de disco no est atrapalhando o tempo
de resposta de IO.

REFERNCIAS:

Windows Performance Monitor Disk Counters Explained


http://blogs.technet.com/b/askcore/archive/2012/03/16/windows-performance-monitor-diskcounters-explained.aspx
Measuring Disk Latency with Windows Performance Monitor (Perfmon)
http://blogs.technet.com/b/askcore/archive/2012/02/07/measuring-disk-latency-with-windowsperformance-monitor-perfmon.aspx

M V T e c h | 315

SQL Server: Alm do Conceito


Blog Post Collection

PROBLEMAS DE REDE ASYNC_NETWORK_IO


H um tempo atrs, fiz uma anlise em conjunto com um amigo, Rafael Carneiro Machado, de problemas
com lentido em um site. O Rafael trabalha comigo, porm no time de Web e ajudou a identificar o
problema que estvamos tendo, assim como a escrever o texto abaixo.

O BJETIVO
Diagnosticar e identificar as possveis causas de lentido em um site que estavam ocorrendo. O
diagnstico iniciou-se de forma geral nos ambientes de Web e Banco de Dados e os contadores de
performance foram sendo refinados de acordo com as evidncias encontradas.
Depois da anlise realizada, foram identificadas evidncias de um problema na rede que interliga os
ambientes de Web e Banco de Dados. Dessa maneira nossos esforos foram direcionados para tanto.

Incidente Reportado: Lentido e timeout em alguns momentos do acesso ao site

A NLISE I NICIAL B ANCO DE D ADOS :


Foi realizada uma anlise em cima da instncia de banco de dados, que hospedava o site e foi identificado
um alto tempo de espera do tipo ASYNC_NETWORK_IO, quase 15%. Porque esse valor alto? Em
particular, nunca tinha visto esse tipo de espera com um valor alto e isto me chamou a ateno, pois
sempre vi um valor prximo a 0% ou no mximo a 2%. Aqui foi o ponto que levou a nossa investigao a
se concentrar que poderia existir um problema relacionado rede, mas o que era exatamente nesse
momento ainda no sabamos.

Figura 1

Esse tipo de espera indica que o SQL Server est respondendo para a aplicao, porm a mesma no est
conseguindo processar no tempo correto.
M V T e c h | 316

SQL Server: Alm do Conceito


Blog Post Collection

Figura 2

Algumas aes que podemos tomar para tentar identificar a causa raiz do problema:

Identificar results sets grandes e verificar com a equipe de sistema se isso realmente est de acordo com
o negcio.
Se nem todas as linhas do result set sero necessrias, devemos alterar o cdigo para restringir essa
quantidade de linhas.
Devemos verificar as configuraes de placa de rede e verificar se no existe nenhum problema.
Validar os componentes de rede entre a aplicao/cliente e a instancia do SQL Server

A NLISE I NICIAL WEB:


No foi identificado nenhum time-out no ambiente Web, o que tnhamos era a demora do Banco de Dados
em responder as requisies dos servidores de aplicao. Isso pode ser identificado pela quantidade de
conexes com o estado SYN_SENT, porm esta informao apenas indica que a primeira ao do ThreeWay-Handshake foi iniciada, onde a origem informou ao destino que deseja iniciar uma comunicao.
Normalmente no vemos este estado de conexo, pois as comunicaes de SYN, SYN-ACK e ACK ocorrem
quase de forma instantnea exceto em casos como este, onde o servidor de destino demora a enviar a
resposta do SYN origem, porm no existia registro de time-out. Monitoramos os pacotes entre os
servidores de aplicao e banco de dados e pudemos ver que o servidor de banco de dados estava
demorando para enviar a resposta, mas respondia a requisio dos servidores de aplicao:

M V T e c h | 317

SQL Server: Alm do Conceito


Blog Post Collection
Figura 3

Nesse momento, suspeitvamos que o problema pudesse estar ocorrendo por falta de portas TCP para
realizar a comunicao devido a um alto trafego de dados. Foi realizado um monitoramento e a mdia de
conexes TCP em portas distintas em cada servidor era de 800, independente do destino. Se levarmos em
conta que por padro a quantidade de portas dinmicas no Windows 2008 de 16384 portas (49152 a
65535), ainda sobram mais de 15 mil portas livres:

Figura 4

Figura 5

O que poderia estar acontecendo era uma limitao nas portas dinmicas dos servidores de banco. Essa
nossa suspeita no se confirmou, pois dificilmente o problema estava na falta de portas altas nos
servidores de aplicao.
Outro detalhe importante que no poderamos deixar de lado, era que o trfego entre Web e Banco de
Dados passava por um appliance de balanceamento, um intrusion prevention system (IPS), Firewall e
outros equipamentos de rede fsica.

A NLISE DETALHADA
Aps anlise inicial, foi constatada a possibilidade de um problema de rede, a partir desse ponto uma
nova investigao foi realizada com foco neste quesito utilizando as ferramentas de anlise de
performance do prprio sistema operacional, o Perfmon.

O S CONTADORES UTILIZADOS FORAM :


Network Interface

% Network Utilization

M V T e c h | 318

SQL Server: Alm do Conceito


Blog Post Collection
Output Queue Length
% Network Utilization Sent
% Network Utilization Received
Packets Outbound Errors
Bytes Total/sec
Current Bandwidth
Packets/secPackets Sent/sec
Packets Received/sec
Packets Received Unknown
Packets Received Discarded
Packets Outbound Discarded
Packets Sent Unicast/sec
Processor

% DPC Time
DPCs Queued/sec

TCPv4

Connection Failures
Segments/sec
Connections Established
Connections Reset
Segments Received/sec
Connections Passive
Connections Active
Segments Retransmitted/sec
Segments Sent/sec

AMBIENTE DE BANCO DE DADOS

M V T e c h | 319

SQL Server: Alm do Conceito


Blog Post Collection

Figura 6

Os itens que mais se destacaram foram a quantidade de pacotes recebidos descartados e com erro, alm
disso, o nmero de segmentos TCP retransmitidos e de conexes com falha tambm esto altos.

Figura 7

M V T e c h | 320

SQL Server: Alm do Conceito


Blog Post Collection

Figura 8

A figura 8 mostra os segmentos TCP que precisaram ser retransmitidos por algum erro de rede.
Outro ponto de destaque a quantidade de conexes TCP com falha. O fabricante recomenda que este
contador no ultrapasse o nmero de 10 conexes TCP com falha por hora. No ambiente de banco de
dados este valor est com uma mdia de 20. As figuras 9 e 10 mostram esse comportamento.

Figura 9

M V T e c h | 321

SQL Server: Alm do Conceito


Blog Post Collection

Figura 10

AMBIENTE WEB

Figura 11

No ambiente Web no tnhamos qualquer indcio na camada fsica de erros, porm o mesmo problema
identificado no ambiente de Banco de Dados ocorre no ambiente Web. Esse problema trata-se da camada
de transporte, vrias conexes com falha e retransmitidas.

M V T e c h | 322

SQL Server: Alm do Conceito


Blog Post Collection

Figura 12

O padro de segmentos retransmitidos se repete no ambiente Web, consequncia das conexes TCP com
falhas.

Figura 13
Esse comportamento no ambiente web foi detectado em todos os servidores da farm.

R ESOLUO
Esse comportamento foi enviado para equipe de rede, que realizou as aes necessrias na camada fsica
dos equipamentos fazendo assim com que o trafego de pacotes ocorresse com sucesso. O site em questo
apresentou uma melhora significante, onde seu carregamento inicial passou de 14 segundos para apenas
2,8 segundos.

CONCLUSO

Por algum motivo relacionado a rede, o Banco de Dados estava com muitos pacotes com erros e
descartados e isso gerava a necessidade de retransmisso dos mesmos, ocasionando demora na entrega
M V T e c h | 323

SQL Server: Alm do Conceito


Blog Post Collection
das informaes que a aplicao demandava. O resultado final era a lentido no acesso e carregamento
do
site.
Foi constatado que at mesmo para iniciar a comunicao entre Web e Banco de Dados o problema
ocorria.
O servidor Web enviava o pacote de SYN, o qual o servidor de banco de dados recebia o pacote e enviava
o ACK. Este pacote de ACK estava sendo corrompido em algum ponto e a aplicao informava ao banco
de dados que ainda no havia recebido sua confirmao (ACK), fazendo com que o Banco de Dados
tentasse envi-lo novamente.
Este perodo entre tentativas e falhas at que o ACK seja enviado corretamente e a comunicao
estabelecida, um exemplo de como a retransmisso de pacotes TCP pode impactar na performance do
site. Essa retransmisso no ocorre apenas durante o processo de Three Way Handshake, mas tambm
quando a comunicao j est estabelecida e efetivamente os dados esto sendo enviados do banco de
dados para os servidores de aplicao.

REFERNCIAS:

http://msdn.microsoft.com/pt-br/library/ms179984.aspx
http://en.wikipedia.org/wiki/Handshaking
http://support.microsoft.com/kb/929851/en-us
http://msdn.microsoft.com/pt-br/library/ms179984.aspx

M V T e c h | 324

SQL Server: Alm do Conceito


Blog Post Collection

Suspect database - MSDTC in-doubt transaction


Em uma bela madrugada, onde todas as coisas obscuras aparecem, um dos servidores de um cluster
falhou e executou um failover para um outro n. At esse momento nada de estranho e esse o
comportamento esperado.

PROBLEMA
Ao verificar os bancos de dados da instancia que sofreu o failover me deparei com o status de suspect
em um deles. Nesse ponto comeou a investigao de como isso aconteceu e como resolver!

CONSEGUI ENCONTRAR NO ERRORLOG AS SEGUINTES MENSAGENS:


Attempting to initialize Microsoft Distributed Transaction Coordinator (MS DTC). This is an informational
message only. No user action is required.
QueryInterface
failed
for
DTC_GET_TRANSACTION_MANAGER_EX::ITransactionDispenser:
0x80004005(failed to retrieve text for this error. Reason: 15105).
QueryInterface failed for ITransactionDispenser: 0x80004005(failed to retrieve text for this error.
Reason: 15105).
Attempting to initialize Microsoft Distributed Transaction Coordinator (MS DTC). This is an informational
message only. No user action is required.
SQL Server detected a DTC/KTM in-doubt transaction with UOW {07372A47-24B9-4BC3-A6510260624FFF8E}. Please resolve it following the guideline for Troubleshooting DTC Transactions.
An error occurred while recovering database XXX. Unable to connect to Microsoft Distributed
Transaction Coordinator (MS DTC) to check the completion status of transaction (0:-222014414). Fix MS
DTC, and run recovery again.
An error occurred during recovery, preventing the database XXX (database ID 5) from restarting.
Diagnose the recovery errors and fix them, or restore from a known good backup. If errors are not
corrected or expected, contact Technical Support.

A aplicao que utilizava essa database tambm utilizava Microsoft Distributed Transaction Coordinator
(MSDTC) e tudo indicava que alguma coisa se perdeu no caminho da comunicao entre o MSDTC da
aplicao e do banco de dados.
No meu caso eu tinha um agravante: o cluster no possua uma instncia do MSDTC, ou seja, utilizava o
MSDTC local.

M V T e c h | 325

SQL Server: Alm do Conceito


Blog Post Collection
Quando uma instncia do SQL Server 2008 ou superior inicializada em um cluster, ela tenta encontrar
uma instncia do MSDTC para comunicao na seguinte ordem:

Dentro do grupo do cluster onde reside o recurso do SQL Server


Dentro de outros grupos do cluster
Instncia MSDTC local

RESOLUO
Eu no sabia o que tinha acontecido com MSDTC e resolvi tomar uma ao para deixar meu banco de
dados online e depois tentar resolver qualquer problema.

Utilizei o comando abaixo:

sp_configure show advanced options, 1


go
reconfigure
go
sp_configure in-doubt xact resolution, 2
go
reconfigure
go
sp_configure show advanced options, 0
go
reconfigure
go

E depois trouxe o banco de dados ONLINE.


Podem existir outras formas de resolver esse problema, porm essa ao permitiu que meu banco de
dados ficasse online e pude executar um DBCC CHECKDB que para meu alivio retornou sem nenhum erro!
Antes de liberar meu banco de dados para produo novamente voltei a configurao padro

M V T e c h | 326

SQL Server: Alm do Conceito


Blog Post Collection
sp_configure in-doubt xact resolution, 0
go
reconfigure
go

Outra alterativa seria visualizar a view sys.dm_tran_active_transactions, essa view mostra algumas
informaes sobre as transaes com uso do MSDTC.
Os campos: transaction_uow, transaction_state, dtc_state so campos que devem ser olhados com
cuidado em uma anlise pois contem informaes importantes.

Assim voc pode identificar o status da sua transao e pode tomar a ao necessria que cabe ao seu
ambiente.

CONCLUSO

Quando a instncia SQL Server executou um failover para o outro n do cluster, a instncia passou a se
comunicar com o MSDTC local do novo n, que no tinha informaes das transaes registradas no n
anterior.
Ao tentar iniciar o processo de recovery do banco de dados, o SQL Server encontrou informaes sobre
transaes distribudas que no haviam sido terminadas (confirmadas ou abortadas) antes da falha. O SQL
Server entrou no processo de validar as informaes do LOG e questionou o MSDTC a respeito das
transaes, e o novo MSDTC local no tinha informaes a respeito destas transaes. Por esse motivo o
SQL Server no foi capaz de resolve-las e desta forma interrompeu o processo de recovery ocasionando o
estado de suspect
A melhor soluo para que isso no ocorra ter uma instancia do MSDTC dentro do cluster.
M V T e c h | 327

SQL Server: Alm do Conceito


Blog Post Collection

R EFERNCIAS :
How to configure DTC for SQL Server in a Windows 2008 cluster
Opo de configurao de servidor in-doubt xact resolution
sys.dm_tran_active_transactions

M V T e c h | 328

SQL Server: Alm do Conceito


Blog Post Collection

Felipe Ferreira
www.templar.com.br/blogs/Felipe

A carreira de DBA est morrendo?


Com a popularidade da nuvem crescendo a cada dia uma das perguntas que eu recebo frequentemente
: a carreira de DBA est morrendo? O que voc vai fazer da vida no futuro?
Neste artigo eu irei dar a minha opinio pessoal sobre o futuro da nossa amada profisso e tentar acalmar
aqueles que j comearam a procurar uma nova carreira.
A primeira coisa que eu gostaria de falar que quando a gente comeou a trabalhar com TI ns sabamos
que esta era uma carreira diferente de muitas outras. Uma carreira dinmica e empolgante que se
reinventa o tempo todo, com novidades tecnolgicas aparecendo todos os anos e mudando todo o
panorama da rea. Ns escolhemos uma profisso que nos obriga a continuar estudando, aprendendo e
evoluindo. E esse o pensamento que eu gostaria que vocs leem este artigo.
O papel do Administrador de Banco de Dados no est desaparecendo, ns no somos uma espcime
ameaada de extino e no entraremos nesta lista em um futuro prximo. A nuvem no a nossa
inimiga. O mercado de dados est apenas evoluindo e a nuvem est trazendo diversas novidades que iro
nos dar mais poder, mais opes.

N O MERCADO DE HOJE NS TEMOS DOIS PROBLEM AS MUITO COMUNS :

1. As empresas no conseguem encontrar profissionais suficiente


Todos sabemos disso. Eu tenho certeza que todos conhecem
diversas empresas que tem vagas em aberto a diversos meses, j
entrevistaram dezenas de pessoas e simplesmente no conseguem
encontrar ningum adequado para a vaga.
2. As empresas querem manter os seus custos o mais baixo possvel
As empresas querem ter lucro e ns acabamos de sair de uma
grande crise mundial. Isso significa que as empresas esto
constantemente tentando encontrar formas de melhorar a sua
produtividade e manter os seus custos o mais baixo possvel.

Em um cenrio como esse as ferramentas que a nuvem nos fornece servem tanto para melhorar nossa
produtividade como DBA e tambm para ajudar a empresa a economizar dinheiro. Vamos pensar um
pouco, quantas tarefas a gente realiza diariamente que no trazem nenhum valor real para o negcio?
Sem dvida que quando estamos planejando uma nova soluo de alta disponibilidade ou realizando
performance tuning naquela consulta lenta ns podemos ver o valor que isso ir trazer para a empresa.
M V T e c h | 329

SQL Server: Alm do Conceito


Blog Post Collection
No primeiro caso, ir garantir que todas as aplicaes estejam de p e rodando quando a empresa precisa
e o segundo ir ajudar com que o servidor aguente a carga de trabalho, execute mais sesses
simultaneamente e fazer com que nossos clientes internos e externos fiquem mais felizes. Mas e aquele
tempo que voc perdeu tentando encontrar mais espao em disco para os seus bancos de dados?
Tentando encontrar espao em disco para armazenar os backups porque o banco de dados cresceu mais
do que o previsto. E o tempo que voc gasta instalando atualizaes no Windows e no SQL? Em algumas
grandes empresas ns temos times de administradores de storage e infra-estrutura que iro se preocupar
com essas tarefas que usei como exemplo, mas essa no a realidade de todo mundo. A grande maioria
de pequenas e mdias empresas possui apenas um pequeno time que responsvel por mltiplas reas.
E porque isso? Volte alguns pargrafos acima nos itens 1 e 2 da minha lista que voc ir entender. Eu
espero voc ler.
Agora vamos tentar imaginar uma outra realidade. Vamos imaginar um mundo onde eu recebo um alerta
de falta de disco para armazenar os meus backups. A nossa empresa adquiriu a pouco tempo uma outra
empresa, o que fez com que o crescimento dos bancos fosse muito maior do que o previsto originalmente
e ns ficamos sem espao em disco. Ento ao invs de esperar dias/meses por um processo de compra
de mais discos eu vou at um portal Web e alguns cliques do mouse depois eu tenho 1TB extra de disco
disponvel. Tudo que preciso fazer agora abrir o SQL Management Studio e alterar os meus Jobs de
backup para utilizar a nova rea de disco. Problema resolvido em menos de 15 minutos.
Vamos imaginar um mundo onde eu possa pegar todos aqueles banco de dados pequenos que eu tenho,
bancos que no so muito importantes para o negcio (sim, ns todos temos vrios desses bancos, no
tente mentir para voc mesmo) e agora vamos mover esses bancos para a nuvem para economizar
recursos do servidor local para as bases mais crticas. Quem sabe eu consiga at diminuir o nmero de
servidores necessrios localmente assim eu no preciso me preocupar com licenas, suporte, aplicar
patches naquela mquina. Isso no seria timo? E que tal se livrar completamente dos ambientes de
homologao e testes e substituir eles por mquinas virtuais na nuvem que eu posso simplesmente
desligar quando no estiverem em uso, economizando dinheiro para a empresa? E aquelas tabelas
enormes, que contem milhes de registros e nos causam problemas todos os dias, no seria timo
substituir aquela soluo complexa de particionamento que ns desenvolvemos para gerenciar dados
histricos ou pouco acessados e ao invs disso permitir que o SQL Server gerencie automaticamente esses
dados, movendo os registros antigos para a nuvem, enquanto mantem os dados acessveis para o cliente
de forma transparente?
A nuvem realmente algo que vai mudar a carreira de muitos, mas no algo que ir matar o papel do
administrador do banco de dados e destruir famlias. Mas ao invs disso, algo que ir nos tornar mais
eficientes, que ir nos fornecer ferramentas e opes que permitam que a gente nos foque em tarefas
que iro trazer realmente valor para a empresa, utilizar de forma mais eficiente o hardware existente,
para tornar nossas vidas mais fceis. Ento abrace as mudanas, da mesma forma que abraamos todas
as outras novas tecnologias que vieram antes dela e use cada tecnologia como uma ferramenta para te
ajudar a ter sucesso no seu trabalho.

M V T e c h | 330

SQL Server: Alm do Conceito


Blog Post Collection

Criando um datawarehouse para testes


Para fazer testes com bases de diferentes tamanhos eu utilizo o datawarehouse dos testes da TPC.
Rapidamente, para quem no conhece, a Transaction Processing Performance Council, ou TPC para os
ntimos (no pergunte o que aconteceu com o outro P), a organizao que define alguns benchmarks
que todos os fabricantes utilizam para fazer testes de performance, com isso ela mantem a lista das
configuraes de Hardware + Software com a melhor performance, o melhor custo x benefcio e assim
por diante.
Para os meus testes eu utilizo o TPC-H, que um teste de Decision Support, ou seja, utiliza uma base no
formato datawarehouse, e no a base OLTP. Se voc deseja fazer esse teste com uma base OLTP acredito
que possa usar o mesmo procedimento com o teste TPC-E, apesar de nunca ter procurado. Temos N
formas de criar as bases de dados da TPC-H, irei partir para a mais manual de todas por nos dar maior
liberdade para fazer N testes.
Ento mos na massa. Toda a estrutura da base de dados e tabelas est na documentao oficial do
bechmarch
TPC-H,
que
vocs
podem
encontrar
no
endereo
http://www.tpc.org/tpch/spec/tpch2.14.0.pdf. Mas vamos facilitar as coisas.

P ASSO 1:
- Criar nossa base de dados. Aqui eu no vou colocar nada de dicas, melhores prticas de como criar, quais
opes habilitar e desabilitar na base de dados, porque isso vai ficar de lio de casa para vocs, testar
carregar os dados com diversas opes e ver a diferena de tempo entre uma forma e outra. Irei fazer
outros posts fazendo essas comparaes futuramente. Ento vamos apenas criar nossa base com os 2
filegroups que precisaremos para os prximos passos, o filegroup LOAD_FG ser nosso filegroup de
Staging, muita gente cria uma base de dados separada para ser a rea de Staging, nesse caso, estamos
criando na mesma base de dados em um filegroup separado; o filegroup DATA_FG o filegroup com os
dados j tratados, nosso datawarehouse final.

1: CREATE DATABASE TPCH


2: ON PRIMARY
3: (
NAME
= tpch1g_root,
4:
FILENAME
= "D:\TPC\tpch1g.mdf",
5:
SIZE
= 10MB,
6:
FILEGROWTH
= 10MB),
7: FILEGROUP
DATA_FG
8:
(name=tpch1g_data1,filename='D:\TPC\tpch1g.ndf',size=2048mb,fileg
rowth=1024Mb),
9:
10: FILEGROUP
LOAD_FG
11:
(name=tpch1g_load1,
filename='D:\TPC\load1g.ndf',size=2048mb,filegrowth=1024mb)
M V T e c h | 331

SQL Server: Alm do Conceito


Blog Post Collection
12:
13: LOG ON
14:
(name=tpch1g_log,
filename='C:\TPC\tpch1G.ldf',size=1024mb)

Obs.: Lembre-se da dica do post anterior do Instant File Initialization para criar grandes bases de dados e
realizar as cargas: http://www.templar.com.br/blogs/felipe/2013/02/24/instant-file-initialization/

P ASSO 2:
- Criar nossas tabelas no Filegroup LOAD_FG, o nosso filegroup de staging.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:

USE TPCH
GO
create table PART
(P_PARTKEY
P_NAME
P_MFGR
P_BRAND
P_TYPE
P_SIZE
P_CONTAINER
P_RETAILPRICE
P_COMMENT
on LOAD_FG

int
varchar(55)
char(25)
char(10)
varchar(25)
int
char(10)
float
varchar(23)

not null,
not null,
not null,
not null,
not null,
not null,
not null,
not null,
not null)

create table SUPPLIER


(S_SUPPKEY
S_NAME
S_ADDRESS
S_NATIONKEY
S_PHONE
S_ACCTBAL
S_COMMENT
on LOAD_FG

int
char(25)
varchar(40)
int
char(15)
float
varchar(101)

not null,
not null,
not null,
not null,
not null,
not null,
not null)

create table PARTSUPP


(PS_PARTKEY
PS_SUPPKEY
PS_AVAILQTY
PS_SUPPLYCOST
PS_COMMENT
on LOAD_FG

int
int
int
float
varchar(199)

not null,
not null,
not null,
not null,
not null)

create table CUSTOMER


(C_CUSTKEY
C_NAME
C_ADDRESS
C_NATIONKEY

int
varchar(25)
varchar(40)
int

M V T e c h | 332

not
not
not
not

null,
null,
null,
null,

SQL Server: Alm do Conceito


Blog Post Collection
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:

C_PHONE
C_ACCTBAL
C_MKTSEGMENT
C_COMMENT
on LOAD_FG

char(15)
float
char(10)
varchar(117)

not null,
not null,
not null,
not null)

create table ORDERS


(O_ORDERKEY
O_CUSTKEY
O_ORDERSTATUS
O_TOTALPRICE
O_ORDERDATE
O_ORDERPRIORITY
O_CLERK
O_SHIPPRIORITY
O_COMMENT
on LOAD_FG

bigint
int
char(1)
float
date
char(15)
char(15)
int
varchar(79)

not null,
not null,
not null,
not null,
not null,
not null,
not null,
not null,
not null)

create table LINEITEM


(L_ORDERKEY
L_PARTKEY
L_SUPPKEY
L_LINENUMBER
L_QUANTITY
L_EXTENDEDPRICE
L_DISCOUNT
L_TAX
L_RETURNFLAG
L_LINESTATUS
L_SHIPDATE
L_COMMITDATE
L_RECEIPTDATE
L_SHIPINSTRUCT
L_SHIPMODE
L_COMMENT
on LOAD_FG

bigint
int
int
int
float
float
float
float
char(1)
char(1)
date
date
date
char(25)
char(10)
varchar(44)

not null,
not null,
not null,
not null,
not null,
not null,
not null,
not null,
not null,
not null,
not null,
not null,
not null,
not null,
not null,
not null)

create table NATION


(N_NATIONKEY
N_NAME
N_REGIONKEY
N_COMMENT
on LOAD_FG

int
char(25)
int
varchar(152)

not null,
not null,
not null,
not null)

create table REGION


(R_REGIONKEY
R_NAME
R_COMMENT
on LOAD_FG

int
char(25)
varchar(152)

not null,
not null,
not null)

P ASSO 3:
M V T e c h | 333

SQL Server: Alm do Conceito


Blog Post Collection
Feito isso j temos nossa base de dados e as tabelas no nosso filegroup de staging, agora precisamos dos
dados para carregar nessas tabelas. Para isso vamos usar o DBGen, a ferramenta fornecida pela TPC para
gerar os arquivos de dados. A TPC fornece esse aplicativo como uma soluo do Visual Studio em C++,
voc pode fazer o download do cdigo fonte aqui, como sei que nem todos os DBAs possuem o Visual
Studio completo instalado, ento vou disponibilizar os executveis j compilados aqui no blog, voc pode
baixar o aplicativo compilado aqui.
Para utilizar s descompactar (ou compilar caso voc tenha baixado o cdigo fonte), abrir um prompt
de comando, navegar at a pasta com o cdigo compilado e executar:

dbgen vf s 1

Sendo o s 1, a quantidade de GB que voc deseja gerar, no exemplo, sero criados arquivos para popular
todas as tabelas acima, totalizando 1Gb em tamanho. Para criar uma base de 10Gb, 50Gb, 100Gb voc s
precisa alterar o valor no parmetro
Os outros dois parametros, vf verbose para mostrar todos os passos na tela e o f de force para
sobreescrever arquivos existentes no disco. Digite dbgen ? para ver todas as opes.

P ASSO 4:
Carregar os dados! Aqui temos N opes, e aqui que a brincadeira comea.. se voc quiser pode
simplesmente usar um BULK INSERT e carregar direto os dados para as tabelas do filegroup LOAD_FG e
depois criar pacotes do SSIS ou scripts T-SQL para mover os dados para o filegroup Data_FG, pode criar
pacotes do Integration Services para carregar tudo, pode usar o BCP, enfim.. pode usar toda a criativade
que Odin lhe deu para ajudar as pessoas que s querem fazer as consultas, testar desempenho, tentar
criar um columnstore index, etc, aqui vai a sintaxe do comando BULK INSERT:

1: bulk insert
(FieldTerminator =
2: bulk insert
(FieldTerminator =
3: bulk insert
(FieldTerminator =
4: bulk insert
(FieldTerminator =
5: bulk insert
(FieldTerminator =
6: bulk insert
(FieldTerminator =
7: bulk insert
(FieldTerminator =

REGION from 'C:\tpc\Region.tbl' with


'|', RowTerminator ='|\n',tablock)
CUSTOMER from 'C:\tpc\Customer.tbl' with
'|', RowTerminator ='|\n',tablock)
NATION from 'C:\tpc\nation.tbl' with
'|', RowTerminator ='|\n',tablock)
PART from 'C:\tpc\part.tbl' with
'|', RowTerminator ='|\n',tablock)
SUPPLIER from 'C:\tpc\SUPPLIER.tbl' with
'|', RowTerminator ='|\n',tablock)
PARTSUPP from 'C:\tpc\partsupp.tbl' with
'|', RowTerminator ='|\n',tablock)
ORDERS from 'C:\tpc\orders.tbl' with
'|', RowTerminator ='|\n',tablock)

M V T e c h | 334

SQL Server: Alm do Conceito


Blog Post Collection
8: bulk insert LINEITEM from 'C:\tpc\LINEITEM.tbl' with
(FieldTerminator = '|', RowTerminator ='|\n',tablock)

E isso pessoal, no arquivo compilado acima eu tambm adicionei o QGEN que gera 22 consultas pesadas
para vocs testarem os servidores. S digite na linha de comando QGEN.exe > consultas.sql que ele ir
gerar a consulta, ou abra os arquivos .SQL que esto na pasta e editem os filtros/etc.

Nos prximos posts vou usar essa base de dados para realizar testes de carga e comparaes de
desempenho.

M V T e c h | 335

Оценить