Blog Archives

T-SQL Tuesday #20 – T-SQL Best Practices

Hi Guys,

This month the subject for T-SQL Tuesday is “T-SQL Best Practices” chosen by Amit Banerjee (Twitter|Blog) . I will describe here a problem that happened some days ago in a customer, and just changing a little thing in the query made all the difference.

The customer told me that some queries have been running slowly, so my job there, was dig further and find what have been wrong.

I found out that all of these queries have been using “convert implicit” and none of indexes have been used. And just put the value of where clause in quotes the index began to be used. I’ll put some some code below to illustrate the example.

create table #temp ( id int not null, idVendor varchar(100))

go

alter table #temp add constraint PK primary key (id)

go

insert into #temp (id,idVendor)

values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6)

go

create nonclustered index ix_teste on #temp(idVendor)

go

select idVendor from #temp

where idVendor = 1

Executing the query we have the execution plan below.

Image1 Image2

As we can see, the nonclustered index didn’t solve my problem because a convert_implict was made to satisfy the query.

To solve this query just put the value of idVendor between quotes like this:

select idVendor from #temp

where idVendor = ‘1’

and we have the follow execution plan:

Image3 Image4

So, just doing a T-SQL best practice we avoided a convert_implicit and an index scan for the query.

Dica do Dia: Lista de Servidores SQL Server

Pessoal,

Apenas uma dica do dia: Ontem precisava acessar uma instancia do SQL Server, porem eu nao tinha o management studio instalado, bom qual recurso a ser usado? Acertou quem disse sqlcmd. Como eu não sabia o nome da instancia um comando do sqlcmd me ajudou muito o sqlcmd /L ou -L. Esse comando te retorna  uma lista dos servidores de SQL Server que ele encontrar na rede, a partir dai é só correr pro abraço. Abaixo segue uma imagem de como é retornado a lista para o usuario

Obs: Com powershell também existe uma solução bem legal, porem como eu nao sou expert nao consegui fazer. 😦

Até mais,
Marcos Freccia
MCTS SQL Server 2008
@SQLFreccia

Problema com Job de Backup

Pessoal,

Alguns dias eu recebi um e-mail de um job de backup que nao tinha disparado com sucesso, a mensagem de erro dizia o seguinte: The process could not be created for step 1 of job 0xE081DC71A38E3740BE2F0A0C0C5F3FA8 (reason: The system cannot find the file specified). Depois de muitas analises eis que com a ajuda de Felipe Ferreira (Twitter|Blog) vimos que no job que disparava esse backup o step estava configurado como mostra a figura abaixo.

Porem na caixa Command foi inserido um script normal e nao um script invocando o sqlcmd. Após passar o tipo do step para Transact-SQL Script o backup rodou normalmente.

O mais estranho aqui é que a mensagem de erro no log nao condizia com o real problema.

Pessoal hoje era isso, espero que esse post possa servir de ajuda para alguem.

Marcos Freccia
MCTS SQL Server 2008
@SQLFreccia

Transaction Log cheio? E agora?

For the English version, see below!

Pessoal,

Um problema que aconteceu comigo esses dias e gostaria de compartilhar com vocês. Em uma manha recebi a seguinte mensagem:
Msg 9002, Level 17, State 2, Line 3
The transaction log for database ‘MCITP’ is full. To find out why space in the log cannot be reused, see the log_reuse_wait_desc column in sys.databases

Read the rest of this entry

Precedência de tipo de dados

Ola Pessoal,

No ultimo post eu falei sobre como Problemas com conversão implicita pode acabar com seu índice. Ainda no final do post falei que ainda temos mais problemas com a conversão implícita, então esse é o nosso assunto de hoje.

A grande questão aqui é a  precedência do tipo de dados, a precedência também é um serio fator na conversão implícita de dados, mas como?

A precedência de dados diz que certos tipos de dados tem uma certa “vantagem” sobre outros tipos de dados em comparações, conversões, etc.. até ai tudo bem, mas como a precedência pode também ser um empecilho na conversão implícita dos dados e assim acabar com seu índice. Vamos aos testes.

Utilizaremos aqui os mesmos scripts do post anterior.

create table #temp ( id int not null, cdVendedor varchar(100))

go

alter table #temp add constraint PK primary key (id)

go

insert into #temp (id,cdVendedor)

values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6)

go

create nonclustered index ix_teste on #temp(cdVendedor)

go

select cdVendedor from #temp

where cdVendedor = 1

Analisando temos o seguinte plano de execução.

Como vimos nessa consulta estamos realizando uma conversão de um tipo de dado texto (varchar) para um tipo de dado inteiro (int), se analisar o tipo de dados varchar que foi declarado na criação da tabela, o mesmo não tem precedência sobre o tipo de dados int, logo o SQL Server não consegue realizar um índex seek na consulta.

Agora vamos mudar nosso tipo de dado do campo cdVendedor.

drop table #temp

go

create table #temp ( id int not null, cdVendedor int)

go

alter table #temp add constraint PK_2 primary key (id)

go

insert into #temp (id,cdVendedor)

values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6)

create nonclustered index ix_teste on #temp(cdVendedor)

select * from #temp where cdVendedor = 3

Executando a consulta a seguir temos o seguinte plano de execução.

Agora execute a seguinte consulta.

select * from #temp2

where cdVendedor = ‘3’

Abaixo plano de execução.

Agora vimos que como o tipo de dados inteiro (int) tem precedência sobre o tipo de dados texto (varchar) não importa como realizamos nossa consulta, se for com aspas ‘’ ou sem aspas sempre teremos um índex seek.

Caso alguém se interessar em realizar esse mesmo teste com outros tipos de dados me avise depois, mas provável que esse comportamento só ocorra com esses dois tipos de dados no caso de inteiro para texto e vice-versa.

Então pessoal por hoje era isso, espero que seja de utilidade para alguém isso, pois é muito importante realizar uma boa modelagem de dados para não ter problemas mais tarde.

Marcos Freccia
MCTS SQL Server 2008
@SQLFreccia

Problemas com Conversão Implicita

Pessoal,

A dica de hoje é bem simples: CUIDADO COM CONVERSAO IMPLICITA há algum tempo atrás precisei criar alguns índices e tudo ocorreu normalmente, porem ao realizar testes desses índices vi que eles não realizavam um índex seek na minha tabela, mas sim um índex scan L. Isso tudo ocorreu por conta de uma conversão implícita estar acontecendo na minha consulta. Então vamos a uma demonstração de como a conversão pode deixar seu índice ineficaz na consulta.

create table #temp ( id int not null, cdVendedor varchar(100))

go

alter table #temp add constraint PK primary key (id)

go

insert into #temp (id,cdVendedor)

values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6)

go

create nonclustered index ix_teste on #temp(cdVendedor)

go

select cdVendedor from #temp

where cdVendedor = 1

Executando a consulta acima temos o seguinte plano de execução.

Como viram nada adiantou eu criar meu índice, mas será que foi um erro do SQL Server ou meu? Bom eu diria que é um erro nosso ao realizar a declaração dos dados, pois como vocês podem ver o campo cdVendedor é do tipo varchar e antes de realizar a consulta o query optimizer teve que realizar a conversão desse campo para encontrar a melhor forma possível de realizar a consulta. Analisando as informações da consulta temos:

Viram o convert_implicit? Então ele foi o responsável por fazer o SQL Server percorrer toda a arvore do índice para procurar o valor que satisfizesse a consulta, porem foi erro nosso declarar o valor na clausula where de forma errada, o correto então seria declarar a consulta da seguinte maneira.

select cdVendedor from #temp

where cdVendedor = ‘1’

Assim temos o seguinte plano de execução.

E como podem ver não temos mais a conversão do tipo de dado antes da consulta ser executada.

Então pessoal por hoje era isso, espero que vocês tenham aprendido alguma coisa por aqui. Ainda temos mais um empecilho com a conversão implícita de dados, mas isso é assim para isso é um assunto que deixo para um próximo post.

Marcos Freccia
MCTS SQL Server 2008
@SQLFreccia