Jump to content
Diogo_Marcelo

Problema SQL 2012 que não acontece em 2008

Recommended Posts

Diogo_Marcelo

Bom dia,

Tenho uma aplicação que a nivel de base dados utilizada algumas view avançadas.

Na versão mais recente do sql server 2012 express, a consulta as views (joins com tabelas normais) demora cerca de 1 min a processar.

Com a mesma base dados , mesmas views, mesmo computador no sql server 2008 express demora cerca de 3 segundos.

Tenho indices nas tabelas, re-indexação feita a ambas as base dados.

Será que o sql server 2012 tem alguma função que o torna lento? Alguem já teve a mesma situação?

Cumprimentos,

Diogo Marcelo

Share this post


Link to post
Share on other sites
nelsonr

Não tenho mexido muito no 2012, mas já tentaste simplficiar a view aos poucos até detectares em que parte está exactamente o problema?

Share this post


Link to post
Share on other sites
pikax

seleciona a query e faz "Display Estimated Execution Plan" ou CTRL+L e ve onde a query esta a perder mais tempo, e se o sql esta a usar os indices.

EDIT:Convem ser no SQL Management studio

Edited by pikax
  • Vote 1

Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Share this post


Link to post
Share on other sites
Diogo_Marcelo

Sinceramente já nem sei do que possa ser, executei o "Display Estimated Execution Plan", mas nao sei ao certo analisar esta imagem, copiei para cá, para ver se alguem me consegue ajudar a identificar alguma situação.

Podem ver a imagem grande aqui ..

http://speedy.sh/JfX9C/imagem.png

imagem.png

Edited by Diogo_Marcelo

Share this post


Link to post
Share on other sites
Rechousa

Olá,

Na versão mais recente do sql server 2012 express, a consulta as views (joins com tabelas normais) demora cerca de 1 min a processar.

Com a mesma base dados , mesmas views, mesmo computador no sql server 2008 express demora cerca de 3 segundos.

Tenho indices nas tabelas, re-indexação feita a ambas as base dados.

Será que o sql server 2012 tem alguma função que o torna lento? Alguem já teve a mesma situação?

Algumas perguntas:

1) Como migraste a BD para o SQL Server 2012? Copiaste o MDF e LDF e fizeste attach? Fizeste Backup / Restore? Criaste a BD através de um script?

2) Tens as estatísticas atualizadas?

3) Os índices estão atualizados? Vê este artigo, poderá ajudar-te. É sobre REBUILD e REORGANIZE dos índices;

4) Não queres partilhar a query?

5) O plano de execução entre as duas edições do SQL Server (2008 e 2012) é o mesmo?

Reparei que embora estejas a utilizar Clustered Indexes, a tua query acaba por fazer por index scan's (o que me leva a pensar novamente nas estatístifcas e se realmente os índices estão atualizados ou não).

Na tabela linhas_doc tens 6 index scan's, com um peso de 11% cada. 6 x 11% = 66%

Na tabela tab_doc tens 3 index scan's, cum um peso de 6% cada. 3 X 6% = 18%

Só aqui tens 84% do peso da query.

Experimenta um truque - criar a vista como sendo materializada e indexá-la.

Uma vista materializada é aquela em que os dados da vista são escritos fisicamente no MDF, deixando de ser calculados on-the-fly.

Para tal, tens de fazer duas coisas:

a) marcar a vista com SCHEMABINDING - sendo marcada como "SCHEMABINDED", se precisares de alterar a estrutura das tabelas, terás de recriar a vista;

b) criar um INDEX sobre a vista;

Definir a vista com SCHEMABINDING:

CREATE VIEW [dbo].[NomeDaVista]
WITH SCHEMABINDING
AS
SELECT .....

Criação do índice sobre a vista:

CREATE CLUSTERED INDEX [iDX_NomeDaVista] [dbo].[NomeDaVista] ([Campo1], [Campo2]);

Mais informação pode ser obtida aqui.

Espero ter ajudado,


Pedro Martins

Sharing is Knowledge!

http://www.linkedin.com/in/rechousa

Share this post


Link to post
Share on other sites
Diogo_Marcelo

Obrigado pela ajuda pessoal..

Então é o seguinte:

Respondendo em contexto ao Rechousa.

Algumas perguntas:

1) Como migraste a BD para o sql Server 2012? Copiaste o MDF e LDF e fizeste attach? Fizeste Backup / Restore? Criaste a BD através de um script?

R: O problema surgiu num cliente, queixava-se que o processo era bastante lento. Então depois de ter colocado tudo em questão, chegamos a conclusão que só poderia ser da SQL Server Express 2012, visto que o servidor era nova e bastante rápido. Foi instalada uma nova maquina com Windows 7 para testes, e uma instancia SQL 2008 e SQL 2012. A base dados foi reposta como backup/restore, as tabelas e views foram criadas de origem. O mesmo processamento extatamente igual em ambas as instâncias.

A base dados é criada através de script na nossa aplicação de sistema.

2) Tens as estatísticas atualizadas?

R: Não compreendi quais as estatisticas que te referes.

3) Os índices estão atualizados? Vê este artigo, poderá ajudar-te. É sobre REBUILD e REORGANIZE dos índices;

Tendo em conta que a base dados foi criada de origem, penso que isso não será um problema. Fiz tambem o reindexar os indices e removi logs.

4) Não queres partilhar a query?

A tabela vdocsparatransformar é uma view.

SELECT DISTINCT cabec_docBase.id_cdoc,
		 veco_cdoc,
		 tdoc_cdoc,
		 nume_cdoc,
		 conta_cdoc,
		 data_cdoc,
		 balcao_cdoc,
		 Isnull(nome_cdoc, '') AS Nome,
		 total_cdoc * cambio_cdoc AS total_cdoc,
		 requisicao_pr		 AS requ_cdoc,
		 veco_cdoc + tdoc_cdoc AS teste_col,
		 impr_cdoc,
		 atdoccodeid_cdoc,
		 CASE
			 WHEN impr_cdoc = 's' THEN 'S'
			 ELSE ''
		 END   AS impresso,
		 CASE
			 WHEN Ltrim(Rtrim(hash_cdoc)) <> '' THEN 'S'
			 ELSE ''
		 END   AS assinado,
		 CASE
			 WHEN trans.id_cdoc IS NULL THEN 'S'
			 ELSE ''
		 END  AS transformado,
		 CASE
			 WHEN cabec_docBase.estado_cdoc <> 'A' THEN ''
			 ELSE 'S'
		 END   AS anulado
FROM cabec_doc AS cabec_docBase
 LEFT JOIN pedreq
		 ON id_pedreq_cdoc = id_pr
 LEFT JOIN vdocsparatransformar AS Trans
		 ON trans.id_cdoc = cabec_docBase.id_cdoc
 LEFT JOIN linhas_doc
		 ON id_cdoc_lind = cabec_docBase.id_cdoc
WHERE 1 = 1
 AND conta_cdoc = '2111.0022'
 AND veco_cdoc = 'O'
 AND balcao_cdoc LIKE '%01%'
 AND cabec_docBase.id_cdoc IN (SELECT * FROM vdocsparatransformar)
 AND cabec_docBase.id_cdoc <> 1300640317
 AND estado_cdoc <> 'a'
ORDER BY veco_cdoc,
	 tdoc_cdoc,
	 data_cdoc DESC,
	 nume_cdoc DESC

5) O plano de execução entre as duas edições do sql Server (2008 e 2012) é o mesmo?

Executei o mesmo procedimento em sql server express 2008 e deu-me exatamente o mesmo plano. A unica diferença é que a query é executada em 3 segundos, enquanto que no 2012 demora cerca de 1m20s .

Imagem Plano 2008

Imagem Plano 2012

Entretanto vou tentar passar a view para SCHEMABINDING.

Edited by Diogo_Marcelo

Share this post


Link to post
Share on other sites
pikax

esta linha esta correcta?

AND cabec_docBase.id_cdoc IN (SELECT * FROM vdocsparatransformar)

tenta fazer com que as condicoes mais leves e que filtram mais dados, tenta colocar no inicio do where.


Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Share this post


Link to post
Share on other sites
Diogo_Marcelo

Boa tarde Pessoal,

Mais uma vez obrigado pela ajuda.

Fiz o teste no sql server 2012 Profissional e acontece o mesmo.

Para resolver a situação, tentei inverter as condições e melhorar a seleção de registos como indicado pelo pikax e consegui resultado de 0.5 segundos.

Apesar de o problema estar resolvido, acredito que haja algo mais que me está a passar ao lado, visto que isto poderá voltar a acontecer num ou outro select.

select * from
(SELECT DISTINCT cabec_docBase.id_cdoc,
		 veco_cdoc,
		 tdoc_cdoc,
		 nume_cdoc,
		 conta_cdoc,
		 data_cdoc,
		 balcao_cdoc,
		 Isnull(nome_cdoc, '') AS Nome,
		 total_cdoc * cambio_cdoc AS total_cdoc,
		 requisicao_pr		 AS requ_cdoc,
		 veco_cdoc + tdoc_cdoc AS teste_col,
		 impr_cdoc,
		 atdoccodeid_cdoc,
		 CASE
			 WHEN impr_cdoc = 's' THEN 'S'
			 ELSE ''
		 END					 AS impresso,
		 CASE
			 WHEN Ltrim(Rtrim(hash_cdoc)) <> '' THEN 'S'
			 ELSE ''
		 END					 AS assinado,
		 CASE
			 WHEN trans.id_cdoc IS NULL THEN 'S'
			 ELSE ''
		 END					 AS transformado,
		 CASE
			 WHEN cabec_docBase.estado_cdoc <> 'A' THEN ''
			 ELSE 'S'
		 END					 AS anulado
FROM cabec_doc AS cabec_docBase
 LEFT JOIN pedreq
		 ON id_pedreq_cdoc = id_pr
 LEFT JOIN vdocsparatransformar AS Trans
		 ON trans.id_cdoc = cabec_docBase.id_cdoc
 LEFT JOIN linhas_doc
		 ON id_cdoc_lind = cabec_docBase.id_cdoc
WHERE 1 = 1
 AND conta_cdoc = '2111.0022'
 AND veco_cdoc = 'O'
 AND balcao_cdoc LIKE '%01%'	
 AND cabec_docBase.id_cdoc <> 1300640317
 AND estado_cdoc <> 'a') vistaBase
left join (SELECT distinct * FROM vdocsparatransformar) as y				 <<<< EXECUTA SEPARADO APOS PRIMEIRA SELEÇÃO
on vistabase.id_cdoc = y.id_cdoc
where y.id_cdoc is not null
ORDER BY veco_cdoc,
	 tdoc_cdoc,
	 data_cdoc DESC,
	 nume_cdoc DESC

Tenho quase certeza que a microsft modificou os processos de pesquisa, criando algumas dificuldades em querys que funcionavam bem no sql server 2008 e 2005.

Edited by Diogo_Marcelo

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.