Uma consulta como a abaixo, garantida para não retornar nenhuma linha, leva de 0 a 160 segundos em um de nossos servidores:
select col1, col2, col3
from tab1
where 0 = 1
Duas semanas atrás, isso aconteceu seis vezes em um intervalo de 48 horas. Na semana passada, a mesma consulta levou ~ 0 segundos. Eu tenho logs dos SQLs do nosso aplicativo, mas ainda não encontrei nenhum suspeito. Além disso, eu pensei que uma consulta do tipo 0 / onde 0 = 1 nunca atingiu as páginas de dados, por isso deve ser resistente a bloqueios de dados de linha / página / tabela? O esquema não é tocado por nenhum SQL (conhecido).
Como o problema não é consistente e o servidor está sob uma carga muito pesada, eu gostaria de entender a teoria por trás do que está acontecendo antes de anexar o criador de perfil SQL. Outras consultas são executadas sem problemas durante esses atrasos. Um problema conhecido no aplicativo é um alto número de consultas SQL criadas dinamicamente - cerca de 200 mil consultas exclusivas de 850 mil consultas totais (registradas) durante um período de 48 horas, isso pode causar problemas como este?
O servidor está executando o SQL Server 2005 standard edition, 96 GB de RAM, discos na SAN e 4 CPUs / 16 núcleos. Os arquivos e grupos de arquivos do banco de dados estão bem otimizados e não devem ser um problema (mas estamos analisando isso separadamente).
Qualquer indicação para onde procurar é muito apreciada.
Edit: Perfeito! Reproduziu a consulta para adicionar o plano de execução e levou 1 minuto e 35 segundos. Aqui está o plano de execução e a captura de tela mostrando a duração da consulta:
Editar 2: detalhes do tempo das estatísticas para uma segunda execução. Parece ser consistentemente lento no momento, então anexaremos o profiler e o perfmon:
SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 97402 ms.
SQL Server parse and compile time:
CPU time = 0 ms, elapsed time = 0 ms.
fonte
Respostas:
Parece que, mesmo com uma
... WHERE 0 = 1
cláusula, ainda haverá um requisito para umIS
bloqueio de intenção shared ( ) na tabela. Vamos provar isso:Vou começar criando uma tabela de teste:
Agora que tenho minha tabela de teste, em uma sessão (janela de consulta) vou executar o seguinte para colocar um
X
bloqueio exclusivo ( )dbo.MyTestTable1
:Eu posso verificar o bloqueio exclusivo olhando para o
sys.dm_tran_locks
DMV. Em outra sessão (nova janela de consulta), faço exatamente o que sua consulta faz:À primeira vista, vejo que não está terminando. Olhando
sys.dm_exec_requests
, vejo exatamente por que esse é o caso:Eu posso ver aqui que minha
... WHERE 0 = 1
consulta está aguardando umIS
bloqueio para esse objeto (que object_id traduz paradbo.MyTestTable1
).Não estou dizendo que a simultaneidade é um problema seu , mas pelos sons dela você está exibindo os sintomas. O exemplo acima é para provar que você não está isento de bloqueio e bloqueio, mesmo com uma
WHERE
cláusula que nunca retornará dados.Tudo o que podemos fazer é adivinhar, então o que você precisa fazer quando está "demorando muito" é ver exatamente o que essa solicitação está fazendo e que está demorando tanto. Se estiver esperando algo, veja o que está esperando.
fonte
Dependendo do nível de picos e de threads que exigem suas consultas, seu sistema pode simplesmente estar na fila dessa consulta. A contagem padrão de trabalhadores (ou seja, número de threads simultâneos do servidor SQL) para sua instalação deve ser de cerca de 700.
Confira sys.dm_os_schedulers e sys.dm_os_waiting_tasks para ver se isso pode ser um problema.
fonte