Archive

Archive for August, 2014

Erro – STATISTICS IO em Planos Paralelos.

Fala pessoal, beleza?

Estava otimizando uma query nessa tarde, onde a mesma utiliza uma clausula TOP e o seu respective plano era um plano paralelo. Visando identificar onde estavam as maiores leituras dos objetos dessa query utilizei o comando SET STATISTICS IO ON.

Quando fui avaliar na guia “messages” do SSMS (SQL Server Management Studio) percebi que a quantidade de leituras lógicas retornadas pelo comando SET STATISTICS IO ON era um pouco menor do que eu realmente esperava, simplificando: A minha query retornava “X” registros de uma tabela “Y”, no entanto, a quantidade de leituras eram muito menor do que eu tinha no meu retorno do SSMS.

Nesse meio tempo ouvi uma voz me dizendo: “Thiago tenta colocar o MAXDOP(1) pra ver se a query executa mais rápido”. Levando em consideração o conselho, executei a mesma query com o MAXDOP(1), portanto, esperaria ver a mesma quantidade de leituras lógicas que vi anteriormente, correto? Errado.

Quando executei a query utilizando o MAXDOP(1) percebi que a quantidade de registros eram a mesma, no entanto, as leituras lógicas eram diferentes. Pesquisando sobre esse comportamento no BING, encontrei um “Connect Item” da Microsoft que realmente isso é uma comportamento inesperado dentro do produto, conforme abaixo:

https://www.beta.microsoft.com/SQLServer/feedback/details/767250/statistics-io-under-reports-logical-reads-for-parallel-plans

Execute os comandos abaixo para poder similar o mesmo problema que encontrei:

USE AdventureWorks2012;

GO

 

SET NOCOUNT ON;

SET STATISTICS IO ON; –Liga as Estatisticas de IO

DBCC SETCPUWEIGHT(1000) WITH NO_INFOMSGS –O comando garante que o plano paralelo seja utilizado.

GO

SELECT TOP 15000 * FROM Sales.SalesOrderHeader WHERE OrderDate < ‘20080101’;

SELECT TOP 15000 * FROM Sales.SalesOrderHeader WHERE OrderDate < ‘20080101’ OPTION (MAXDOP 1);

DBCC SETCPUWEIGHT(1) WITH NO_INFOMSGS;

Mais porque esse comportamento acontece?

Quando um plano paralelo tem uma clásusula TOP, por algum motive o SQL Server pode encerrar “threads” anteriormente se existem linhas suficientes (não possuo o valor desse threshold) para serem retornadas para o usuário. Esse encerramento interfere com a coleta de estatisticas do comando SET STATISTICS IO, ao contrário, do que acontece com plano sem paralelismo. Quando isso acontece, possivelmente nós veremos a quantidade reportada de IO para um plano paralelo menor do que a quantidade de IO reportado para um plano serial

Obs: Esse comportamento foi corrigido no SQL Server 2014.

Espero que tenham gostado.

Advertisements
Categories: Performance

Parallel SELECT… INTO – SQL Server 2014

Hoje apareci aqui no blog apenas para dar uma dica bem básica. Atualmente o Microsoft SQL Server está na versão 2014. Essa nova versão trouxe muitas features FANTÁSTICAS que possivelmente justifica uma migração da versão anterior (SQL 2012) para a versão atual (SQL 2014).

Uma das deficências das versões anteriores é que não era possível realizar operações de SELECT… INTO em paralelo e em algumas situações pode degradar um pouco do desempenho dessa operação.

Imagine um cenário onde você deve realizar uma operação de inserção de milhões de linhas em uma tabela de “stage” toda noite. E o resultado dessa tabela será trasnformado para um ambiente de data warehouse. Provavelmente essa operação de INSERT seria mais eficiente se fosse feito de forma paralela. Á partir do SQL 2014 esse tipo de operação é possivel, como podemos ver no link abaixo:

http://blogs.technet.com/b/italian_premier_center_for_sql_server/archive/2013/07/24/sneak-peek-on-sql-2014.aspx

A pergunta é: O paralelismo sempre vai me ajudar? A principio eu diria que DEPENDE, pois, pode haver alguns problemas se o paralelismo for utilizado de forma incorreta. Na internet existem diversas “threads” sobre o assunto,mas, recentemente li um artigo que explica de forma muito clara a questão do paralelismo dentro do SQL Server conforme podemos ver no link abaixo:

http://blogs.msdn.com/b/pfebrasilsql/archive/2014/08/21/max-degree-of-parallelism-cxpacket-maxdop.aspx

O principal ponto que gostaria de mostrar aqui é que, caso, exista um cenário onde possivelmente a “feature” de Parallel SELECT… INTO pode estar me prejudicando eu posso “desligar” esse comportamento.

O trace flag 9492 pode ser utilizado para o próposito de desabilitar essa nova feature dentro do SQL Server, lembrando que apenas utilize essa opção avançada se você REALMENTE SABE o que está fazendo. Pois, novas features geralmente sempre trazem melhorias e não o comportamento contrário. Lembre-se, TESTEs são VITAIS.

Obs: Para banco de dados de nível de compatibilidade 110 e superiores o Parallel SELECT … INTO podem ser automaticamente paralelizada se necessário.

Espero que tenham gostado.

Até a próxima.

Categories: Performance

Problemas de Performance com Tabelas variáveis?

Tabelas variavéis apareceram no SQL Server com a intenção de reduzir compilações tornando-se bem popular com sua frequente utilização e em alguns casos mais do que as tabelas temporárias.

A sua famosa utilização deu-se devido ao mito que: “Tabela variável fica na memória e tabela temporária fica no tempdb”. Execute o código abaixo e verifique que mesmo para a tabela variável o SQL Server aloca espaço no tempdb fisicamente.

USE tempdb

go

declare @Tabela table (cod int not null primary key clustered (cod))

insert into @Tabela values(1),(2)

select sys.fn_PhysLocFormatter(%%physloc%%) FROM @Tabela

No entanto, ambos tipos de tabela possuem suas particularidades, pós e contras. Existem diferença entre tabela variável e tabela temporária? Sim várias.

O objetivo desse post não é falar sobre a diferença de ambas, mas, no final do post tem algumas referências sobre o assunto. Recomendo a leitura

O principal problema que já tive com tabelas variáveis foi devido a criação de planos de execução ineficiente, pois, quando uma query é compilada no SQL Server o número de linhas da tabela variável é “desconhecido”. Esse comportamento pode fazer com que o otimizador de consulta realize uma estimativa que pode não ser a melhor trazendo problemas no momento da geração do plano de execução já que a cardinalidade para tabelas variáveis são sempre 1. Eu escrevi sobre isso neste artigo.

A partir do SQL Server 2012 SP2 uma nova trace flag foi adicionada para ajudar nesse ponto.A trace flag 2453 faz com que o SQL Server detecta “linhas suficientes” sendo inseridas em uma tabela variável e faz com que seja disparado uma recompilação da instrução T-SQL para produzir um plano de execução mais eficiente.

Em que cenário a utilização dessa trace flag se aplicaria? Imagine em um ambiente que existem diversos objetos de programação criados e muitos deles apresentam problemas de desempenho devido a utilização da tabela variável. Para ter que alterar todos, isso pode demandar uma boa quantidade de tempo, nesse caso, seria interessante avaliar a utilização do Trace Flag 2453. Ou até mesmo em um ambiente onde o código fonte é disponibilizados por fábricas de softwares terceira e você não possui permissão para alteração do código fonte para mudar as tabelas variáveis para tabelas temporárias

 

Referências:

http://blogs.msdn.com/b/psssql/archive/2014/08/11/if-you-have-queries-that-use-table-variables-sql-server-2012-sp2-can-help.aspx

 

http://epmxperts.wordpress.com/2010/06/23/myth-sql-server-table-variables-vs-temp-tables/

 

http://blogs.msdn.com/b/psssql/archive/2012/08/22/10053781.aspx

Até mais.

 

Categories: Performance