Arquivo

Arquivo do Autor

Nova Geração de Notebooks DELL

16 de agosto de 2008 Deixe um comentário

10 pontos que devem ser observados quanto a performance de uma consulta Parte – 4

8 de agosto de 2008 3 comentários

6.       Substituir o uso de CURSOR pelo comando WHILE + tabelas temporárias ou Variáveis do tipo table.

DECLARE @VendorID Int,

        @Name     VarChar(80)

 

DECLARE Cur_Vendor CURSOR FOR

 SELECT VendorID, Name

   FROM Purchasing.Vendor

 

OPEN Cur_Vendor

 

FETCH NEXT FROM Cur_Vendor

 INTO @VendorID, @Name

 

WHILE @@FETCH_STATUS = 0

BEGIN

       PRINT @Name

 

             FETCH NEXT FROM Cur_Vendor

    INTO @VendorID, @Name

END

 

CLOSE Cur_Vendor

DEALLOCATE Cur_Vendor

GO

 

DECLARE @ROWID Int,

        @Name  VarChar(80)

 

SET @ROWID = 0;

 

SELECT TOP 1

       @ROWID = VendorID,

       @Name  = Name     

  FROM Purchasing.Vendor

 WHERE VendorID > @ROWID

 ORDER BY VendorID

 

WHILE @@ROWCOUNT > 0

BEGIN

  PRINT @Name

 

  SELECT TOP 1

         @ROWID = VendorID,

         @Name  = Name     

    FROM Purchasing.Vendor

   WHERE VendorID > @ROWID

   ORDER BY VendorID

END

GO

 

7.       Verificar se as variáveis no WHERE são do mesmo DataType que a coluna da tabela.

DECLARE @TMP TABLE(Nome VarChar(80) PRIMARY KEY)

 

DECLARE @Nome NVarChar(80)

SET @Nome = ‘Teste’

 

— Gera FULL SCAN

SELECT * FROM @TMP

 WHERE Nome = @Nome

 

GO

 

DECLARE @TMP TABLE(Nome VarChar(80) PRIMARY KEY)

 

DECLARE @Nome VarChar(80)

SET @Nome = ‘Teste’

 

— Gera SEEK

SELECT * FROM @TMP

 WHERE Nome = @Nome

 

8.       Verificar se existe uso de variáveis do tipo Table para grande volume de dados, pois isso pode causar problema de performance já que variáveis do tipo table não usam proveito de paralelismo e não criam estatísticas com os dados da tabela.

9.       Verificar se é possível usar o conceito de Hash Index usando o CheckSum para gerar o número HASH, Caso existam colunas com valores muito grandes as vezes compensa usar o CheckSum para gerar o Hash e depois indexar a coluna hash.

— Create a checksum index.

SET ARITHABORT ON;

USE AdventureWorks;

GO

ALTER TABLE Production.Product

ADD cs_Pname AS CHECKSUM(Name);

GO

CREATE INDEX Pname_index ON Production.Product (cs_Pname);

GO

/*Use the index in a SELECT query. Add a second search

condition to catch stray cases where checksums match,

but the values are not the same.*/

SELECT *

FROM Production.Product

WHERE CHECKSUM(N’Bearing Ball’) = cs_Pname

AND Name = N’Bearing Ball’;

GO

10.       Evite usar a clausula IN.

IF OBJECT_ID(‘tempdb.dbo.#TMP’) IS NOT NULL

BEGIN

  DROP TABLE #TMP

END

 

CREATE TABLE #TMP (ID Int IDENTITY(1,1) PRIMARY KEY)

GO

 

INSERT INTO #TMP DEFAULT VALUES

INSERT INTO #TMP DEFAULT VALUES

INSERT INTO #TMP DEFAULT VALUES

INSERT INTO #TMP DEFAULT VALUES

INSERT INTO #TMP DEFAULT VALUES

GO

 

SET STATISTICS PROFILE ON

SET STATISTICS IO ON

 

SELECT * FROM #TMP

 WHERE ID IN (1,2,3,4,5)

 

 

/*

Coluna argument

 

OBJECT:([tempdb].[dbo].[#TMP]),

       SEEK:(

               [tempdb].[dbo].[#TMP].[ID]=(1) OR

               [tempdb].[dbo].[#TMP].[ID]=(2) OR

               [tempdb].[dbo].[#TMP].[ID]=(3) OR

               [tempdb].[dbo].[#TMP].[ID]=(4) OR

               [tempdb].[dbo].[#TMP].[ID]=(5)

            )

       ORDERED FORWARD

 

Repare no argument que o SQL gerou, ou seja irá acessar uma vez a tabela #TMP para cada opção do IN

podemos confirmar isso no Scan Count do statistics io

 

— IO

Scan count 5, logical reads 10, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 

*/

GO

 

SELECT * FROM #TMP

 WHERE ID BETWEEN 1 AND 5

/*

OBJECT:([tempdb].[dbo].[#TMP]),

       SEEK:(

              [tempdb].[dbo].[#TMP].[ID] >= (1) AND

              [tempdb].[dbo].[#TMP].[ID] <= (5)

            )

       ORDERED FORWARD

 

Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 

Repare na diferença de IO.

*/

 

Espero que tenham gostado, eu adorei J, gostei tanto que vou começar a escrever uma série de artigos sobre o Query Optimizer, fiquem de olho…

10 pontos que devem ser observados quanto a performance de uma consulta Parte 3

8 de agosto de 2008 Deixe um comentário

Seguindo a série de boas práticas em relação a performance…

 

4.      É muito comum durante o desenvolvimento de um código SQL necessitarmos zerar o valor das variáveis que serão utilizadas no código.

Uma dica em relação a performance é que o comando SELECT é mais rápido do que o SET, porém está regra só se aplica quando podemos substituir um bloco de SET por um SELECT por ex:

— Executa um loop zerando o valor de 10 variáveis utilizando SET

— Gere o plano de execução e repare que no plano de execução que no Loop o SQL gera um SELECT para cada comando SET.

DECLARE @i Int, @Test1 int, @Start datetime

DECLARE @V1 Char(6),

        @V2 Char(6),

        @V3 Char(6),

        @V4 Char(6),

        @V5 Char(6),

        @V6 Char(6),

        @V7 Char(6),

        @V8 Char(6),

        @V9 Char(6),

        @V10 Char(6);

 

SET @Test1 = 0

SET @i = 0

SET @Start = GetDate()

WHILE @i < 50000

BEGIN

  SET @V1 =

  SET @V2 =

  SET @V3 =

  SET @V4 =

  SET @V5 =

  SET @V6 =

  SET @V7 =

  SET @V8 =

  SET @V9 =

  SET @V10 =

      SET @i = @i + 1                  

END                               

SET @Test1 = DATEDIFF(ms, @Start, GetDate())

SELECT @test1

 

GO

— Executa um loop zerando o valor de 10 variáveis utilizando SELECT

— Diferente do primeiro plano de execução o SQL gerou apenas 1 instrução para setar os valores para as 10 variáveis.

DECLARE @i Int, @Test1 int, @Start datetime

DECLARE @V1 Char(6),

        @V2 Char(6),

        @V3 Char(6),

        @V4 Char(6),

        @V5 Char(6),

        @V6 Char(6),

        @V7 Char(6),

        @V8 Char(6),

        @V9 Char(6),

        @V10 Char(6);

 

SET @Test1 = 0

SET @i = 0

SET @Start = GetDate()

WHILE @i < 50000

BEGIN

SELECT @V1 = ,

       @V2 = ,

       @V3 = ,

       @V4 = ,

       @V5 = ,

       @V6 = ,

       @V7 = ,

       @V8 = ,

       @V9 = ,

       @V10 = ,

       @i = @i + 1;

END                               

SET @Test1 = DATEDIFF(ms, @Start, GetDate())

SELECT @test1

 

5.       Pequenas dicas para procedures..

a.       Sempre que uma procedure é executada o server envia para o client o número de linhas afetadas pela procedure, normalmente esta informação não é necessária. Desabilitando este comportamento poderemos reduzir o trafego gerado pelo Server e o Client. Portanto sempre que possível inclua o SET NOCOUNT ON no início de suas procedures. Pode ser que isso não gere muita diferença em uma proc que efetua 1 insert mas quando estamos falando de um loop que efetua 1000000 de inserts daí com certeza vai ser um grade ganho de trafego desnecessário que estaria rolando na rede.

b.      Só use a opção WITH ENCRYPTION e WITH RECOMPILE caso seja realmente necessário. Lembre-se de que existem programas que conseguem descriptogravar um proc que está criptografada no banco.

c.       Não inicie o nome de suas procedure com sp… este prefixo é reservado para procedures do sistema, sempre que você executa uma procedure que inicia com sp… o SQL irá procurar a proc no banco Master e se ela não estiver lá então ele irá resolver o nome da proc no banco atual. Evite este passo adicional simplesmente renomeando as procedures para por exemplo usp ou st.

d.      Caso tenha que rodar algum código TSQL no meio da proc evite utilizar o EXEC ao invés disso use a sp_ExecuteSQL pois ao contrário do EXEC a sp_ExecuteSQL irá compilar o SQL para gerar um plano de execução para sua consulta, o quer dizer que caso o plano já tenha sido gerado na próxima execução do código ele irá utilizar o plano que ficou em cachê, evitando a recompilação do código a cada execução.

FIX e Patchs de Correção II

6 de agosto de 2008 Deixe um comentário
Ainda falando sobre atualização e correções do SQL Server, segue um site MUITO bom que contem todos os updates do SQL e qual o número de cada Build.
 
 
Esse vale ir pro favoritos.
 
Categorias:SQL Server

FIX e Patchs de Correção

5 de agosto de 2008 Deixe um comentário

Pessoal vamos ficar atentos para os Fix de correção de erros do SQL Server, não basta atualizar até o último Service Pack e esperar pelo próximo SP pois tem existem várias correções que são lançadas e que ainda não estão em um Service Pack.

 

Nos últimos 2 meses tivemos problema 2 problemas em nossos clientes que estavam com uma versão com um problema que já havia sido corrigido.

 

1º Problema;

 

O primeiro foi em um cliente que utilizava SQL Server 2000 com Service Pack 3, e tivemos um erro que ao rodar uma consulta com um where IS NULL mesmo assim retornava um valor que não era NULL.

Por ex:

 

select * from tabela

where Cod IS NULL

 

O comando acima retornava um Cod que não era null contrariando o filtro do WHERE.

Este problema foi corrigido no SP 4 do SQL 2000, como podemos ver no KB abaixo.

 

FIX: A parallel query may return unexpected results

http://support.microsoft.com/kb/814509/en-us

 

Para resolver temporariamente até o cliente atualizar seu servidor utilizamos a clausula OPTION (MAXDOP 1) nos selects.

 

2º Problema;

 

Outro erro que pegamos foi no SQL Server 2005 SP2 onde ao rodar uma procedure com um texto muito grande e usando a opção WITH ENCRYPTION o SQL gerava um erro.

Este problema foi corrigido com um FIX que já foi lançado e é bem provável que estará entre os FIX de correção que serão lançados com o SP3 do SQL Server 2005, podemos ver mais detalhes do problema e baixar o FIX no KB abaixo.

 

FIX: Error message when you run a long stored procedure that is encrypted in SQL Server 2005: "A stack overflow occurred in the server while compiling the query"

http://support.microsoft.com/kb/934246/en-us

 

Categorias:SQL Server

Scripts and Tools for Performance Tuning and Troubleshooting SQL Server 2005

5 de agosto de 2008 Deixe um comentário

E tem gente que ainda pergunta porque eu gosto da Microsoft!

 

Script Repository: SQL Server

 

Acesse e pegue uma coleção muito boa de scripts para o SQL Server 2005.

 

Aproveitando o embalo acesse o Toolbox do CAT para mais arquivos e aplicativos úteis para SQL.

 

http://sqlcat.com/toolbox/default.aspx

Categorias:SQL Server

Community Zone 2008

1 de agosto de 2008 2 comentários

imagem

Acabei de receber um convite para participar do Community Zone 2008 que será no Hotel Vila Santo Agostinho em Bragança Paulista.

 

Show de Bola! Baseado no que vi dos eventos anteriores a este deve ser muito bom. Fora que irei estar no meio dos maiores influenciadores e colaboradores da Microsoft…

 

Para enviar o convite eles avaliaram a minha contribuição nas comunidades técnicas como:

 

             Fóruns de discussão (quantidade de respostas com alta qualidade e/ou moderação);

             Artigos técnicos publicados na comunidades MSDN e TechNet;

             WebCasts entregues através do MSDN e TechNet;

             Eventos Presenciais;

             Contribuições com grupo de usuários;

             Participação em Projetos dos Centros de Inovação e/ou Adoption Labs da Microsoft

 

Já confirmei minha presença, quando eu voltar conto como foi J

 

Categorias:Não categorizado

Tem lógica ?

25 de julho de 2008 Deixe um comentário

Meu Deus, cada uma que aparece, vejam isso.

 

O mais novo MVP em SQL Server Denis Gobo postou no Blog dele.

 

SQL Teaser: Where Clause Gone Wild

Try to guess what this WHERE clause is supposed to do.

WHERE

r.ApptId IS NULL

AND r.DATE >= ISNULL(NULL , ‘1/1/1900’)

AND r.DATE < DATEADD(d , 1 , ISNULL(NULL , ‘1/1/3000’))

AND

–Filter on resource

( ( NULL IS NOT NULL

AND r.DoctorResourceID IN ( NULL ) )

OR ( NULL IS NULL ) )

AND –Filter on facility

( ( NULL IS NOT NULL

AND r.FacilityID IN ( NULL ) )

OR ( NULL IS NULL ) )

AND –Filter on Inactive

ISNULL(r.inactive , 0) = 0

ORDER BY

ISNULL(g.LAST , ) + ISNULL(g.FIRST , )

If you think I made that up, then you are in for a surprise. This is actually part of a query, I found it here: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3662895&SiteID=1

This NULL IS NULL and NULL IS NOT NULL stuff is just killing me. I wonder why this person did not get an answer yet…..Enjoy your weekend  🙂

Categorias:SQL Server

WebCast – XML no SQL Server 2005

23 de julho de 2008 Deixe um comentário

Hoje, fiz a WebCast falando de XML no SQL Server 2005,

Segue os arquivos utilizados nas Demos bem como o PPT. 
Obrigado a todos que estiverem na sala.
 
Abraço.
Categorias:SQL Server

Idera VS Minha Coffee Mug

10 de julho de 2008 Deixe um comentário

Eles são rápidos, o Jorge Aguilar da Idera já me ligou e respondeu o e-mail dizendo que irão me mandar um Package da Idera.

 

I Love the Power of the Internet.

 

Ou será que o FBI apertou os caras? Hahahaha.

Categorias:Não categorizado