T-SQL Tuesday #025 – Truques


Este mês o Sr. Allen White (Blog | Twitter)  pediu para as pessoas dizerem quais truques elas utilizam para deixar o trabalho mais fácil…

Nós temos muitos códigos em powershell que ajudam a melhorar o dia, mas, powershell,,, aahh,,, se você usar o google, poderá encontrar muita gente escrevendo bons códigos que podem ajudá-lo.

Eu escrevi uma coisa legal, mas em T-SQL, para criar bases em mirror,,, Sim, eu sei, você pode encontrar um monte de blogs falando sobre como criar esse tipo de ambiente,,, mas eu vou fazer isso usando SQLCMD dentro do Management Studio,,, por quê? só pela diversão…

Eu vou pular a parte da criação dos end-poins porque você já sabe…

A parte legal está logo depois da versão em inglês,,,

Hi, i try translate all the text above, sorry if have some mistakes,,,

This month Mr. Allen White (Blog | Twitter) ask people to say what tricks we use to make our job easier…

We have a lot of code in powershell helping to improve the day, but, powershell,,, aahh,,, if you use the google will find a lot of people writing good scripts to help you.

I going to write some nice,, but in T-SQL, just to create a database mirror,,,, Yes, I know, you can find a lot of blogs talking about who to create a database mirror,,, but I will do this using the SQLCMD inside the Management Studio,, why? just for fun…

I´ll skip the creation of end-points because you already know…

The good part is here:


/* Change the principal server name and instance */
:SETVAR principal_server "SERVERNAME\INSTANCE1"
/* Change the mirror server name and instance */
:SETVAR mirror_server "SERVERNAME\INSTANCE2"
/* in this case I use the same server, but you can add one more setvar and add the other server */
:SETVAR server "SERVERNAME"
/* Database name to mirror */
:SETVAR db "DB_NAME"

:connect $(principal_server)

alter database $(db) set recovery full

backup database $(db)
to disk = 'D:\DB01\inst01\$(db).bak'
with compression, stats = 5

backup log $(db)
to disk = 'D:\DB01\inst01\$(db).trn'
with compression, stats = 5

go
:connect $(mirror_server)

restore database $(db)
from disk = 'D:\DB01\inst01\$(db).bak'
with file = 1,
move '$(db)' to 'D:\DB01\local\$(db).mdf',
move '$(db)_log' to 'D:\DB01\local\$(db).ldf',
norecovery, nounload, stats = 5

restore database $(db)
from disk = 'D:\DB01\inst01\$(db).trn'
with norecovery, nounload, stats = 5

alter database $(db)
set partner = 'TCP://$(server):5022'
go

:connect $(principal_server)

/* In this part you can change the setvar if was created other one */
alter database $(db)
set partner = 'TCP://$(server):5023'

 

T-SQL Tuesday #23 – Joins


Para o pessoal não ficar corrido entre escrever uns posts meia boca e se preocupar com os preparativos para o SQLPASS, o pessoal resolveu dar uma adiantada no T-SQL Tuesday desse mês,,,

Este mês ele é hospedado por Stuart Ainsworth (Blog | Twitter) e fala sobre joins..

Quer saber mais sobre Joins?

Vamos lá,,,

meu exemplo é bem simples,,, mostra os waits que estão acontecendo no SQL…

select
w.session_id,
w.wait_duration_ms,
w.wait_type,
w.blocking_session_id,
w.resource_description,
s.program_name,
t.text,
t.dbid,
s.cpu_time,
s.memory_usage
from sys.dm_os_waiting_tasks w
inner join sys.dm_exec_sessions s on
w.session_id = s.session_id
inner join sys.dm_exec_requests r on
s.session_id = r.session_id
outer apply sys.dm_exec_sql_text (r.sql_handle) t
where s.is_user_process = 1

Ele vai tentar associar a requisição ao wait.

T-SQL Tuesday #21 – Depois arrumo esse código,,,


Dessa vez o anfitrião do T-SQL Tuesday é o próprio idealizador Adam Machanic (Blog | Twitter).

E de uma forma diferente, não é na Terça-feira,,, por quê?

Porque não importa, desde que funcione pode ser zuado mesmo,,, o tópico desse mês é sobre “mostrar seu código lixo para o mundo”,,,

Todo mundo já escreveu um código uma vez ou outra,,,, todo o DBA tem aquele conjunto de scripts que o ajudam a identificar alguns problemas, fazer um tunning, arrumar alguma coisa,,, E com certeza todo mundo tem aquele código que hoje, pega para olha e começa a dar risada de como é que teve coragem de fazer uma coisa como aquela…

Meu exemplo é bem simples, O código é horrível, demora demais mas, funciona,,,

Ele troca os dados de posição de uma coluna específica.

WITH cteTableTel AS (
    SELECT
        ROW_NUMBER() OVER (ORDER BY NEWID()) AS n,
        SOBRENOME
    FROM CLIENTES
    )
UPDATE CLIENTES
   SET ENDERECO = (
       SELECT ENDERECO
       FROM cteTableTel
       WHERE cteTableTel.n = CLIENTES.ID)
Esse código funciona, não é nada bonito, não é performático, mas para a necessidade de uma base de treino com dados reais ele ajuda bastante,,,
Se você percebeu ele tem um problema,,, sabe qual é?
Como você garante que todas as linhas da tabela de clientes realmente estão em uma sequencia? Você pode ter apagado algum registro uma hora ou outra,,, Logo, haverá cliente que o endereço não vai ser atualizado,,
Já sei, você nem reparou nesse problema,,, você deve estar pensando: “por que ele esta fazendo um update na tabela de clientes se ele está usando uma CTE?”, ou também, “Legal, ele está fazendo isso em uma tabela que tem algum tipo de ID e quando tem aquelas tabelas que não da pra usar nada de referencia?”
Como eu disse, ele não é performático, e eu nem tinha me atentado nesses detalhes na época,,,  Houveram duas situações que me refizeram rever esse código: o primeiro caso dos usuários que não tinham os dados alteradores e o último… ai com muita vontade resolvi reescrever,,,
E ele ficou mais ou menos assim:
;WITH cte AS (
    SELECT
        ROW_NUMBER() OVER (ORDER BY NEWID()) AS n1,
        ROW_NUMBER() OVER (order by SOBRENOME) AS n2,
        SOBRENOME
    FROM CLIENTES
    )
UPDATE c1
   SET SOBRENOME = c2.SOBRENOME
   from cte as c1
   inner join cte as c2
   on c1.n1 = c2.n2

Dessa vez não tem problema com o usuário sem o dado alterado, performance melhorada em quase 90% e pouco importa se a tabela em algum registro para referencia,,,

Eu comparei a execução dos 2 códigos em uma tabela com um pouco mais de  3 milhões de linhas e o segundo código demorou quase 4 horas para finalizar,,, já o primeiro código eu parei a execução dele depois de 2 SEMANAS executando.

Tenho códigos piores no meu repositório? claro que sim. Esse é apenas um exemplo de um dos piores que já fiz…

Qual é o seu? tem coragem mostrar?

T-SQL Tuesday #20 – Melhores Práticas


Neste mês o tema escolhido pelo Sr. Amit Banerjee (blog | twitter) foi: Melhores Práticas,,,

A algum tempo atrás escrevi um post com “Dicas para otimizar suas funções SQL”,,, vou adicionar algumas coisas que acho interessante com este post aqui.

  • Comentários,,,,

Lembra daquela procedure que fazia uma validação de alguma coisa em algum lugar ??? Lembra por que você declarou aquele campo bit no começo ??? Não? tem certeza que sabe? acha que era para alguma coisa importante?

Uma coisa que acho muito importante em todo o código, mas são poucas as pessoas que fazem direito e menos ainda as que fazem, é comentar o que ele faz,,,

Não custa muito adicionar algumas linhas com algum tipo de descritivo do que aquilo deveria fazer, quem fez, quando fez, qual a versão, algum exemplo,,,

Lembre-se: Uma hora ou outra o código pode precisar de manutenção,,, ela pode ser feita por você ou outra pessoa,,, em todo o caso,,, é sempre bom ter alguma coisa para te ajudar a lembrar,,,

Ex:

/*
Nome: usp_mostra_nome_base
Versão: 2.0
Data de criação: 11-07-2011
Data da última modificação: 12-07-2011

Autor: Ricardo Leka Roveri
Últuma modificação executada por: Ricardo Leka Roveri

Script:
Esta procedure server para listas o nome das bases existentes no sistema.

Exemplo
exec usp_mostra_nome_base

Versão 1:
Autor: Ricardo Leka Roveri

nesta versão a proc faz XYZ

Versão 2:
Autor: Ricardo Leka Roveri

nesta versão a proc faz XYZ ordenado por data de criação

*/

Outra coisa interessante seria comentar partes do código,,, não precisa escrever um livro do motivo que você está fazendo aquele join entre 20 tabelas mas, de uma forma clara, escrever o objetivo dessa bagunça,,,

  • NOLOCK,,,

Você é um fanático por NOLOCK? Legal,,, nada contra,,, mas se vai usar isso umas 40 vezes dentro de uma procedure porque você não declara ele como:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITED;

é legal, ajuda, mais simples pra você e para qualquer outra pessoa que veja seu código…

  • Lembrete,,,

Lembre-se:

A maior parte de vocês não desenvolve coisas pra vocês,,, vocês desenvolvem coisas pra outras pessoas usarem…

Não é porque na sua maquina tudo funciona direitinho que quando for para produção tem que funcionar,,, Você precisa testar,,, faça teste de carga… stresse sua aplicação até ela parar,,, 10,,, 100,,, 1000,,, acessos simultâneos,,,

Existem muitas ferramentas que fazem teste de carga. Ex.: JMeter, o próprio SQL Profiler, etc..

T-SQL Tuesday #19 – Disasters & Recovery


E ai? Blz? Neste mês para o T-SQL Tuesday o tema escolhido pelo Sr. (blog | twitter) foi Desastre & Recover…. Que tema chato,,, hehehe,,,

Muitas pessoas – administradores de rede, gerentes, desenvolvedores, dba´s acidentais, etc. – acham que banco de dados é a coisa mais simples do mundo, só serve pra guardar alguma informação e que aquilo vai fica sempre por lá. Esse pessoal não entende que se tem gente que é especialista em administrar banco de dados é porque por algum motivo obscuro isso é importante.

Muitos não dão valor ao trabalho do Administrador de banco até perder alguma coisa, uma boa galera acha que para manter um banco qualquer pessoa consegue, afinal, não tem muito trabalho pra fazer,,,

Ainda bem que existe esse tipo de gente,,, é ainda mais legal quando alguém me liga no meio da madrugada com aquela voz desesperada pedindo ajuda porque o servidor do banco (que era o mesmo do AD, Exchange, FileServer, DHCP) foi pro espaço e eles não estão conseguindo mais recuperar as coisas…

Muitas vezes vejo o pessoal falando sobre seus planos de backup, que contemplam X ou Y e blá blá blá,,, Mas quando pergunto qual o seu plano de recovery o pessoal olha torto e me mostra o plano de backup…

Pessoal,,,, entendam uma coisa,,,, plano de backup é bonito pra não passar feio na frente da diretoria,,, mas ter plano de recovery é o que realmente importa…

Uma coisa que pergunto pro pessoal é: “O quanto de dados você está disposto a perder?”, claro que quase sempre tenho a mesma resposta, ninguém quer perder nada,,,

Hoje em dia existem várias formas de se prevenir quando a perda de informação:

  • Backup
  • Cluster
  • Mirror
  • Log shipping
  • Replicação
  • Etc.

Claro que cada uma delas tem seus custos,,,

Manter os dados acessíveis é importante isso é disponibilidade,,, mas,,, e quando a casa caiu? Alguém aplicou alguma mudança no ambiente e apagou um monte de registro que não deveria? O storage deu rebuild da LUN e apagou todos os seus discos,,, o Windows deu tela azul…

Iai? É nessa hora que você vai descobrir que seu robô de backup não consegue ler as fitas,,, ou que o software de backup não fazia backup justamente daquela unidade ou base que você precisa… ou mais legal, quase todo o dia você cancelava a rotina de backup porque ela entrava no horário de produção, ai não fazia backup das principais bases…

Neste caso,,, parabéns !!! troca de cidade, apaga essa empresa do currículo, sai correndo,,,

Plano de desastre & recovery é igual a seguro de carro,,, você faz pra não usar,,, mas quando precisa e ele falha o que faz? Chora? Troca?

A pior coisa que pode acontecer em um momento de crise é o pânico. Mantenha a calma, com certeza vão ter pessoas desesperadas correndo que nem baratas tontas tentando qualquer coisa que lembrar ou encontrar na internet.

Lembre-se: você tem que ser assertivo, se você fez a lição de casa não existe situação que não pode ser contornada.

Seu supervisor/gerente/diretor tem que ter maturidade de segurar todas as buchas enquanto você se foca em colocar em ação o plano de desastre.

Uma dica, noticia ruim se dá na hora. Perdeu? Perdeu,,, não da pra recuperar? Já era? Avisa logo…

T-SQL Tuesday #18 – CTEs


Bom,,, para este mês o Sr. Bob Pusateri (twitter | Blog) escolheu o tópico Common Table Expressions (CTE).

Você não sabe o que é? Não faz ideia? Isso é mais comum do que você imagina,,, vejo muitos códigos por ai onde o pessoal de dev poderia utilizar este recurso, mas como ainda estão presos em conceitos antigos do SQL 2000 ou as vezes até mais velhos não fazem ideia de alguns novos recursos interessantes…

Para uma leitura interessante sobre este assunto acesse:

Você vai achar muita coisa voltada pra dev… mas,,, como sou mais um cada de infra,,, achei interessante este código no Site do Sr. Paul Randal (twitter | Blog) sobre wait statistics usando a sys.dm_os_wait_stats, nada muito complexo.

 1: WITH Waits AS
 2:     (SELECT
 3:         wait_type,
 4:         wait_time_ms / 1000.0 AS WaitS,
 5:         (wait_time_ms - signal_wait_time_ms) / 1000.0 AS ResourceS,
 6:         signal_wait_time_ms / 1000.0 AS SignalS,
 7:         waiting_tasks_count AS WaitCount,
 8:         100.0 * wait_time_ms / SUM (wait_time_ms) OVER() AS Percentage,
 9:         ROW_NUMBER() OVER(ORDER BY wait_time_ms DESC) AS RowNum
 10:     FROM sys.dm_os_wait_stats
 11:     WHERE wait_type NOT IN (
 12:         'CLR_SEMAPHORE', 'LAZYWRITER_SLEEP', 'RESOURCE_QUEUE', 'SLEEP_TASK',
 13:         'SLEEP_SYSTEMTASK', 'SQLTRACE_BUFFER_FLUSH', 'WAITFOR', 'LOGMGR_QUEUE',
 14:         'CHECKPOINT_QUEUE', 'REQUEST_FOR_DEADLOCK_SEARCH', 'XE_TIMER_EVENT', 'BROKER_TO_FLUSH',
 15:         'BROKER_TASK_STOP', 'CLR_MANUAL_EVENT', 'CLR_AUTO_EVENT', 'DISPATCHER_QUEUE_SEMAPHORE',
 16:         'FT_IFTS_SCHEDULER_IDLE_WAIT', 'XE_DISPATCHER_WAIT', 'XE_DISPATCHER_JOIN', 'BROKER_EVENTHANDLER',
 17:         'TRACEWRITE', 'FT_IFTSHC_MUTEX', 'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
 18:         'BROKER_RECEIVE_WAITFOR', 'ONDEMAND_TASK_QUEUE', 'DBMIRROR_EVENTS_QUEUE',
 19:         'DBMIRRORING_CMD', 'BROKER_TRANSMITTER', 'SQLTRACE_WAIT_ENTRIES',
 20:         'SLEEP_BPOOL_FLUSH', 'SQLTRACE_LOCK')
 21:     )
 22: SELECT
 23:     W1.wait_type AS WaitType,
 24:     CAST (W1.WaitS AS DECIMAL(14, 2)) AS Wait_S,
 25:     CAST (W1.ResourceS AS DECIMAL(14, 2)) AS Resource_S,
 26:     CAST (W1.SignalS AS DECIMAL(14, 2)) AS Signal_S,
 27:     W1.WaitCount AS WaitCount,
 28:     CAST (W1.Percentage AS DECIMAL(4, 2)) AS Percentage,
 29:     CAST ((W1.WaitS / W1.WaitCount) AS DECIMAL (14, 4)) AS AvgWait_S,
 30:     CAST ((W1.ResourceS / W1.WaitCount) AS DECIMAL (14, 4)) AS AvgRes_S,
 31:     CAST ((W1.SignalS / W1.WaitCount) AS DECIMAL (14, 4)) AS AvgSig_S
 32: FROM Waits AS W1
 33:     INNER JOIN Waits AS W2 ON W2.RowNum <= W1.RowNum
 34: GROUP BY W1.RowNum, W1.wait_type, W1.WaitS, W1.ResourceS, W1.SignalS, W1.WaitCount, W1.Percentage
 35: HAVING SUM (W2.Percentage) - W1.Percentage < 95;
 36: GO

T-SQL Tuesday #17–Apply


O tópico deste mês para o T-SQL Tuesday é o operador apply,,,

Caso você não faça ideia de pra que serve o apply leia aqui.

Para este post vou coloca um script simples usando o apply.

Ele não faz nada muito importante, apenas mostra as 20 querys que mais gerão stress de disco:

SELECT TOP 20 SUBSTRING(qt.text, (qs.statement_start_offset/2)+1,
((CASE qs.statement_end_offset
WHEN -1 THEN DATALENGTH(qt.text)
ELSE qs.statement_end_offset
END – qs.statement_start_offset)/2)+1),
qs.execution_count,
qs.total_logical_reads, qs.last_logical_reads,
qs.min_logical_reads, qs.max_logical_reads,
qs.total_elapsed_time, qs.last_elapsed_time,
qs.min_elapsed_time, qs.max_elapsed_time,
qs.last_execution_time,
qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
WHERE qt.encrypted=0
ORDER BY qs.total_logical_reads DESC