Estou tendo um problema com uma consulta SQL que é executada e executada, mas nunca é concluída. O banco de dados é um banco de dados SQL do Azure.
Minha tabela tem dezenas de milhões de linhas e se parece com isso:
CREATE TABLE [dbo].[MyData](
[CustomerId] [int] NOT NULL,
[TagName] [nvarchar](100) NOT NULL,
[TagValue] [real] NULL,
[TimeStamp] [datetime2](7) NOT NULL,
[status] [int] NULL,
CONSTRAINT [PK_MyData] PRIMARY KEY CLUSTERED
(
[CustomerId] ASC,
[TagName] ASC,
[TimeStamp] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
Minha instrução select se parece com isso:
DECLARE @StartDate as datetime
DECLARE @EndDate as datetime
Select @StartDate = LastReadDT from MyData_LastDT_Read
Select @EndDate = dateadd(minute,30,@StartDate)
SELECT CAST([TagName] as varchar(100)) as [tag],
CAST(isnull(TagValue, 0) as real) as tagvalue,
CAST([TimeStamp] as datetime) as [DataTimeStamp],
CAST(192 as int) as [status]
FROM [dbo].[MyData]
where CustomerID = 1
and TimeStamp <= @EndDate
and TimeStamp > @StartDate
order by TimeStamp asc
O estranho é que se eu remover as variáveis e e, em vez disso, apenas codificar os valores reais @StartDate
na cláusula where, a consulta retornará resultados em menos de 1 segundo. Por que codificar os valores na consulta faria uma diferença tão dramática em comparação com as variáveis? Alguma sugestão de como melhorar o desempenho? Infelizmente preciso usar as variáveis, pois essa consulta é executada repetidamente com diferentes intervalos de tempo.@EndDate
TimeStamp
TimeStamp
Isso tem um cheiro de um problema de sniffing de parâmetro. Veja o que eu fiz lá? Punny, certo?
De qualquer forma, Paul White escreveu um ótimo artigo sobre as várias abordagens disponíveis para resolver esse problema, então não vou entrar em detalhes quando você deveria apenas ler o artigo dele. O que você pode tentar rapidamente, porque esta é uma instrução ad-hoc, é forçar uma recompilação usando a
OPTION (RECOMPILE)
dica. Se isso resolver seu problema, você definitivamente está se deparando com o que eu suspeito. No entanto, a melhor maneira de resolver isso corretamente é converter sua instrução em um procedimento armazenado e, em seguida, executar o procedimento armazenado passando os parâmetros de data. Um procedimento armazenado parametrizado não será vítima do problema atual e também deve ser reutilizável.Isso não é determinístico, a menos que a tabela tenha 0 ou 1 linha
Por que não apenas se juntar