【发布时间】:2010-07-05 15:29:41
【问题描述】:
我有一个包含多个表的 SQL Server 2005 数据库。其中一张表用于存储多个设备的时间戳和消息计数器,并具有以下列:
CREATE TABLE [dbo].[Timestamps] (
[Id] [uniqueidentifier] NOT NULL,
[MessageCounter] [bigint] NULL,
[TimeReceived] [bigint] NULL,
[DeviceTime] [bigint] NULL,
[DeviceId] [int] NULL
)
Id 是唯一的主键 (Guid.Comb),我在 DeviceId 和 MessageCounter 列上都有索引。
我要做的是为某个设备找到最后插入的行(MessageCounter 最大的行)。
奇怪的是对设备号的查询。 4(以及除 1 号以外的所有其他设备)几乎立即返回:
select top 1 *
from "Timestamps"
where DeviceId = 4
order by MessageCounter desc
但对设备号的查询相同。 1 需要很长时间才能完成:
select top 1 *
from "Timestamps"
where DeviceId = 1 /* this is the only line changed */
order by MessageCounter desc
最奇怪的是,设备 1 的行数比设备 4 少得多:
select count(*) from "Timestamps" where DeviceId = 4
(returns 1,839,210)
select count(*) from "Timestamps" where DeviceId = 1
(returns 323,276).
有人知道我做错了什么吗?
[编辑]
从两个查询的执行计划中,可以清楚地看到设备 1(下图)在索引扫描中创建了更多的行:
不同之处在于当我将索引扫描节点悬停在执行计划图上时:
Device 4 Actual Number of Rows: 1
Device 1 Actual Number of Rows: approx. 6,500,000
6,500,000 行是一个非常奇怪的数字,因为我的select count(*) 查询为设备 1 返回了大约 300,000 行!
【问题讨论】:
-
也许刷新DeviceID上的索引?
-
能否在两个查询中添加执行计划?比我们知道的,它改变了什么。然后我们可以猜到,为什么会这样...... :-)
-
好的,看起来统计信息不同步 - 我假设数据库设置为自动更新统计信息。听从 OMG Ponies 的建议
标签: sql sql-server database sql-server-2005 sql-server-profiler