我有一个叫读数有> 7600万行中它是我上运行该查询表:查询慢上聚集索引一定的标准
declare @tunnel_id int = 13
SELECT TOP 1 local_time, recorded_time
FROM readings
WHERE tunnel_id = @tunnel_id
ORDER BY id DESC
的id列是一个BIGINT,设置为主键,并且具有聚集索引,并且在tunnel_id字段上还有一个索引。
作品很棒,在我尝试的20个不同的tunnel_id中,大约有16个返回不到一秒钟。但是,在最后4个左右,查询需要40秒,并使用数十万次读取。
我试着修改查询到这一点:
SELECT TOP (1) local_time, recorded_time
FROM readings
where id = (
SELECT TOP 1 id
FROM readings
WHERE tunnel_id = 13
ORDER BY id DESC
)
这再一次只有几tunnel_id的慢。更让我更困惑的是内部选择快速运行缓慢的ID,如果我硬编码最大的ID而不是子查询它也快速运行。
我在这里错过了什么让这个查询执行得不好?
编辑意见:
Tunnel_id不是唯一的,每个通道都有数以百万计的行。这是在Sql Server 2012上运行的。
我包含来自快速和慢速运行的实际执行计划,它们是相同的。
快速:
慢:
但你可以看到,在不到一秒钟的第一执行而第二个需要51秒。
我猜它的很大一部分是你的'ORDER BY ID DESC' - 默认情况下,你可能在'id ASC'上有聚簇索引,所以有可能在后台发生排序。 – JNK
为什么你首先有一个子查询? –
建议尝试使用tunel_id的参数封装在存储过程中进行查询。 otimizer可能会发生一些奇怪的事情,以及如何缓存执行计划。一般来说,根据Micrsoft Press的Book 70-461,查询Microsoft SQL Server,与特定查询相比,查询计划对存储过程的缓存效率更高。只是一个想法。 – Karl