【问题标题】:MAX keyword taking a lot of time to select a value from a columnMAX 关键字花费大量时间从列中选择一个值
【发布时间】:2012-02-27 08:16:33
【问题描述】:

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

这是我在 proc 中使用的查询

 DECLARE @Id bigint    
 SELECT @Id = MAX(ExecutionID) from ExecutionLog where TestID=50881    
 select @Id  

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

【问题讨论】:

  • 为什么需要执行100次?
  • 您有关于 TestID 的索引吗?或者根据数据更好地加入 TestID 和 ExecutionID? ExecutionID 也是 bigint 还是只是 int?
  • @Damien_The_Unbeliever...好吧,它需要为多个测试执行此操作

标签: sql-server


【解决方案1】:

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

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 必须要做的。

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

【讨论】:

  • 我们在executionlog表上有索引,但是索引只针对executionID而不针对testID。需要 testID 吗?
  • 在这种情况下是的,因为您正在扫描 TestID。
  • Thanx @MicSim,这行得通...在我将索引与 TestID 分组后,需要一秒钟来获取记录:)
  • 用解释性注释编辑。
【解决方案2】:

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

因此,例如,您可以编写这样的 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 擅长的处理类型 - 不要通过迭代代码中的 TestIDs 来削弱系统。

如果您需要将许多测试 ID 传递到此类查询的存储过程中,请查看表值参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-10
    • 1970-01-01
    • 2017-04-09
    • 1970-01-01
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多