索引查询有时需要几分钟才能完成

时间:2018-03-16 16:09:39

标签: sql-server azure-sql-database

我有一个查询(约95%的时间)几乎立即在生产Azure SQL数据库上执行。在SSMS(生产中)中运行查询表明我的非聚集索引正在与索引搜索一起使用(成本为100%)。

但是,数据库随机突然进入同一查询无法执行的状态。它总是从调用应用程序中超时。在这一集发生时登录SSMS我可以手动执行查询,并且最终会在执行几分钟后完成(因为SSMS中没有时间限制与调用应用程序的时间限制)。

在我允许查询完全执行而没有超时之后,我可以随后使用即时结果再次执行查询。调用应用程序现在也可以再次使用即时结果调用它。似乎允许它在没有超时的情况下完全执行,可以清除发生的任何问题,并使执行恢复正常。

监控服务器指标显示CPU利用率没有真正的问题或尖峰,这表明服务器在此期间处于压力状态。应用程序中的所有其他查询仍然可以正常执行。甚至是使用同一个表和非聚集索引的查询。

表格

CREATE TABLE [dbo].[Item] (
    [Id]             UNIQUEIDENTIFIER NOT NULL,
    [UserId]         UNIQUEIDENTIFIER NULL,
    [Type]           TINYINT          NOT NULL,
    [Data]           NVARCHAR (MAX)   NULL,
    [CreationDate]   DATETIME2 (7)    NOT NULL,
    CONSTRAINT [PK_Item] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_Item_User] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User] ([Id])
);

此表中有数百万行。

索引

CREATE NONCLUSTERED INDEX [IX_Item_UserId_Type_IncludeAll]
    ON [dbo].[Item]([UserId] ASC, [Type] ASC)
    INCLUDE ([Data], [CreationDate]);

发出查询

SELECT
    *
FROM
    [dbo].[Item]
WHERE
    [UserId] = @UserId
    AND [Data] IS NOT NULL

当我今天在SSMS中捕获它时,我还修改了查询以从where子句中删除AND [Data] IS NOT NULL。例如:

SELECT
    *
FROM
    [dbo].[Item]
WHERE
    [UserId] = @UserId

此查询立即执行,执行计划显示正在正确使用索引。添加回AND [Data] IS NOT NULL会导致查询再次变慢。这个Data列可以容纳大量的JSON数据,因此我不确定它是否与它有任何关系。

在发生集并且我的查询长时间运行时正在运行sp_WhoIsActive,表明readsphysical_readscpuused_memory始终是 - 随着查询继续执行而增加。有趣的是,query_plan列在运行时为NULL,因此我无法看到它实际使用的是什么计划。虽然我总能看到在此后手动运行索引搜索。

  • 为什么这个查询会进入一个状态,在这个状态下执行需要很长时间,而大多数时候它会以近乎即时的结果执行?我们可以看到它正确地利用它的非聚集索引作为搜索操作。
  • 为什么允许查询在SSMS中完全执行(与调用应用程序执行时的超时)似乎可以解决未来的问题?
  • 如何避免这些类型的剧集?

1 个答案:

答案 0 :(得分:0)

我会检查几件事......

1.您的查询没有良好的索引,因为您正在进行选择*以及data is not null

,所以下面会有一个好的索引
create index nci on table(userid,data)
include(rest of columns in select )

2.尝试更新此表的统计信息和索引,如果存在索引碎片或陈旧统计信息,这将有所帮助

3.尝试option(recompile)提示,看看参数嗅探是否有问题