MAX关键字需要花费大量时间从列中选择一个值

时间:2012-02-27 08:16:33

标签: sql-server

好吧,我有一张40,000,000多条记录的表,但是当我尝试执行一个简单的查询时,完成执行需要大约3分钟。由于我在我的c#解决方案中使用相同的查询,它需要执行超过100次,因此解决方案的整体性能受到了极大的打击。

这是我在proc

中使用的查询
 DECLARE @Id bigint    
 SELECT @Id = MAX(ExecutionID) from ExecutionLog where TestID=50881    
 select @Id  

任何提高性能的帮助都会很棒。感谢。

2 个答案:

答案 0 :(得分:4)

你在桌子上有什么索引?听起来你没有任何对这个特定查询有用的东西,所以我建议尝试这样做:

CREATE INDEX IX_ExecutionLog_TestID ON ExecutionLog (TestID, ExecutionID)

......至少。您的查询是按TestID过滤的,因此这需要是复合索引中的主列:如果TestID上没有索引,则SQL Server将使用 扫描整个表 ,以便找到TestID = 50881

的行

考虑SQL表上的索引可能与在层级和多层次的大书后面找到的索引相同。如果您正在寻找某些东西,那么您可以在'T'下手动查看TestID,然后在TestID下为ExecutionID设置一个子标题。如果没有TestID的索引条目,您必须阅读整本书以查找TestID,然后查看是否有提及ExecutionID的内容。这实际上是SQL Server必须做的事情。

如果您没有任何索引,那么您会发现查看命中该表的所有查询很有用,并确保其中一个索引是聚簇索引(而不是非聚簇索引)。

答案 1 :(得分:1)

尝试将所有内容重新设置为以基于集合的方式工作的内容。

因此,例如,您可以编写一个这样的select语句:

;With OrderedLogs as (
     Select ExecutionID,TestID,
       ROW_NUMBER() OVER (PARTITION BY TestID ORDER By ExecutionID desc) as rn
     from ExecutionLog
)
select * from OrderedLogs where rn = 1 and TestID in (50881, 50882, 50883)

然后,这将同时找到3个不同测试的最大ExecutionID。

您可能需要将该结果存储在表变量/临时表中,但希望您可以继续构建更大的单个查询,以并行处理所有结果。

这是SQL应该擅长的那种处理 - 不要通过迭代代码中的TestID来破坏系统。

如果需要将许多测试ID传递给存储过程以进行此类查询,请查看表值参数。