Meus aplicativos executam consultas em um banco de dados do SQL Server.
Em muitos casos, vejo o benefício de um plano de execução: por exemplo, clico pela primeira vez em um botão para
SELECT * from Tasks
WHERE IdUser = 24 AND
DATE < "12/12/2010" and DATE > "01/01/2010"
leva 15 segundos na primeira vez, 8 segundos nos seguintes tempos.
EDIT: EU USO CONSULTAS PARAMETRIZADAS.
Então eu tenho uma melhoria de 7 segundos na segunda vez.
Agora, como eu executar o aplicativo novamente (assim que eu faço uma nova conexão de banco de dados) na primeira vez que levará 15 segundos, a segunda vez 7 ...
Como é possível dizer ao SQL Server para armazenaros planos de execução, pelo menos, para lembrá-los nos mesmos dias? Ou, no entanto, como posso obter benefícios de planos de execução já calculados? Se usuários diferentes executam a mesma consulta, é uma maneira de dizer ao sql server que seja inteligente o suficiente para usar o mesmo plano de execução, mesmo que, nesse caso, provavelmente o IdUser seja diferente.
No software eu tenho alguns parâmetros, por isso pode ser a próxima execução da consulta terá diferentes MinDate e MaxDate, mas isso afetará o plano de consulta?
Respostas:
2 para resposta № 1Use consultas parametrizadas para maximizar as chances de o plano ser armazenado em cache
SELECT * from MYTasks
WHERE IdUser = @UserId AND DATE < @enddate and DATE > @startdate
O SQL Server faz parametrização automática, mas pode ser bastante conservador em relação a isso.
Você pode obter algumas dicas sobre a reutilização de planos a partir do seguinte
SELECT usecounts, cacheobjtype, objtype, text, query_plan, value as set_options
FROM sys.dm_exec_cached_plans
CROSS APPLY sys.dm_exec_sql_text(plan_handle)
CROSS APPLY sys.dm_exec_query_plan(plan_handle)
cross APPLY sys.dm_exec_plan_attributes(plan_handle) AS epa
where text like "%MYTasks%" and attribute="set_options"
2 para resposta № 2
O SQL Server fará isso para você - qualquer plano de execução é armazenado enquanto houver espaço disponível.
No entanto, você pode fazer muito para aumentar as chances de os planos de execução serem armazenados e reutilizados - o que você precisa cuidar é criar idêntico Consultas SQL - qualquer coisa em um espaço extra pode fazer com que o SQL Server considere duas consultas diferentes e não reutilize um plano de consulta existente.
Então, portanto:
seja consistente em suas consultas - sempre soletre as coisas de maneira idêntica (atente para maiúsculas / minúsculas, espaços em branco,
dbo.
prefixos etc.)use parâmetros em vez de valores literais; Se você usar valores literais, seus planos de consulta não serão reutilizados e eles preencherão desnecessariamente o cache do plano.
tente evitar
SELECT *
- isso significa que o otimizador de consulta tem menos opções- como você deseja todas as colunas, geralmente é necessário fazer uma varredura no índice clusterizado. Se você especificar as três, cinco, seis colunas que realmente precisa, há uma chance de haver um índice que cubra a consulta (contém todas as colunas nas quais você está interessado) e, portanto, a análise de consulta poderia usar esse índice e fazer uma varredura / índice de índice busca isso (e reutiliza esse plano).
Então, ao invés do seu SQL agora, use isso:
SELECT (list of fields)
FROM dbo.MYTasks
WHERE DATE < @EndDate and DATE > @StartDate
Isso deve aumentar significativamente a reutilização do plano de consulta.
0 para resposta № 3
Você já executou o SQL Server Profiler? Em caso afirmativo, você tem certeza de que o tempo extra é gasto na compilação da declaração e na geração de planos de execução?
A partir da descrição do seu problema, os 7 segundos adicionais podem ser hora de configurar a conexão inicial com o banco de dados. Talvez você já tenha descartado isso. Eu não sei.
Uma preocupação adicional é o cache de dados. A primeira vez que você acessa dados, o SQL Server os carrega em seu cache. Isso pode reduzir o tempo de consultas subseqüentes (supondo que ele possa conter todos os dados).