【问题标题】:Performance Issue - Select firstdate per month on a very big table性能问题 - 在一张非常大的桌子上每月选择第一个日期
【发布时间】:2017-10-17 13:24:31
【问题描述】:

我有一张非常大的桌子(超过 1.4 亿行,大小约为 230 GB)。有一个名为“date_dim”的列,带有一个聚集索引 asc。表中存储了 2015 年的所有数据。

我现在的目标是获取存储数据的一个月的第一个日期。所以可能是 1 月的数据从 5 日开始。所以我必须构建一个“动态”查询。

为了检索这些数据,我创建了以下查询:

SELECT
    *
FROM (
  SELECT               
    date_dim
    ,row_num = ROW_NUMBER() OVER (PARTITION BY MONTH(date_dim) ORDER BY date_dim ASC)
   FROM myTable_2015 WITH (NOLOCK)
 ) AS s
WHERE
    row_num = 1
ORDER BY
    1

现在我的问题是查询需要很长时间才能获取数据。是否有其他选择来构建性能更好的查询?对于为我的具体情况选择如此大的表,您有什么性能建议吗?

实际上我无法对表本身进行任何更改,只有“读取”访问权限...

【问题讨论】:

  • 你不能从日期表中得到它吗?
  • 不,因为我需要每月存储数据的第一个日期...

标签: sql sql-server performance tsql row-number


【解决方案1】:

如果我理解您的问题,有两个快速选择

Select BOMonth = min(date_dim)
 From  myTable_2015 
 Group By year(date_dim),month(date_dim)

甚至

Select BOMonth = min(date_dim)
 From  (select distinct date_dim from myTable_2015 ) A
 Group By year(date_dim),month(date_dim)

【讨论】:

  • 第二个查询应该快得多。
【解决方案2】:

使用窗口函数:

SELECT distinct min([date_dim]) 
     over (partition by Year([date_dim]), month([date_dim])) as [FirstDate]
FROM myTable_2015
ORDER BY [date_dim]

【讨论】:

    【解决方案3】:

    如果您有 1.4 亿行,那么很有可能每个月的第一天都有

    select distinct(date_dim) 
    from   myTable_2015 WITH (NOLOCK)
    where  day(date_dim) = 1 
    

    或者你可以在第一个 x 上隔离

    select min(date_dim) 
    from   myTable_2015 WITH (NOLOCK)
    where  day(date_dim) <=5 
    group by month(date_dim)
    

    【讨论】:

      猜你喜欢
      • 2020-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多