【发布时间】:2012-12-05 10:50:12
【问题描述】:
我正在处理一个非常大的表(每天大约添加 270 万行),它具有以下结构:
CREATE TABLE [dbo].[Result](
[ResultDate] [date] NOT NULL,
[Thing1Id] [int] NOT NULL,
[Num] [int] NOT NULL,
[Thing2Id] [int] NOT NULL,
CONSTRAINT [PK_Result] PRIMARY KEY CLUSTERED
(
[ResultDate] ASC,
[Thing1Id] ASC,
[Num] ASC
))
由于集群主键位于 ResultDate、Thing1Id 和 Num 上,我希望以下查询是最佳的:
SELECT Thing2.*
FROM dbo.Result
INNER JOIN Thing2 ON Thing2.Id = result.Thing2Id
WHERE
ResultDate >= '2012-01-01'
AND
ResultDate <= '2012-01-30'
AND Thing1Id = 23
如您所见,查询在 1 月 12 日查找特定 Thing1 的结果。
但是,执行计划表明通过添加以下索引可以获得巨大的性能提升:
CREATE NONCLUSTERED INDEX [IX_Missing]
ON [dbo].[Result] ([Thing1Id],[ResultDate])
INCLUDE ([Num],[Thing2Id])
当然,添加此索引确实会大大提高性能。
有人能解释一下原因吗?就我而言,应该使用聚集主键充分缩小结果范围,添加它会使索引大小变得更大并增加不必要的开销。
我可以对表进行不同的索引以获得更好的性能吗?
(请注意,实际上该表实际上是合并的 2 个表,数据每天从一个表转移到另一个表,数据按月分区)。
【问题讨论】:
-
我敢打赌,即使只是在
dbo.Result(Thing2Id)上添加一个非聚集索引也会大大加快您的查询速度,因为Thing2Id是一个外键并在您的INNER JOIN Thing2 ON Thing2.Id = result.Thing2Id中使用声明... -
是的,你是对的。我已经在 Thing2Id 上添加了一个可以加快速度的索引,但我没有在帖子中包含它,因为我对聚集索引更感兴趣。谢谢。
-
我不明白为什么 Thing2Id 上的索引会对此查询有所帮助。仅仅因为它有一个 FK 而添加一个索引,对这样的大表的伤害可能比它的帮助更大。
-
很可能,Thing1id 更有选择性,或者 SQL Server 正在做某种索引交集。发布执行计划,我们就知道了。
-
你能同时发布query execution plans吗?
标签: sql-server performance clustered-index sql-execution-plan