2

我有一个大表,我的服务器上的全表扫描大约需要 2 分钟(150 个 mio 数据集)。

该表包含一年中各个日期的销售交易。它按日期索引。

如果一个月中至少存在一个数据集,我正在寻找一种有效的方法来获取每个月的信息。

通常我会这样做:

select month, count(*)
from transaction_table
group by month

这需要太长时间。

该查询不需要计算每个月的每个数据集,它只需要查看每个月是否存在至少一个数据集。

在单个查询中是否有更高效的方法来执行此操作?

4

4 回答 4

4

如果它是按日期索引的,那么以下应该很快:

select distinct year(date), month(date)
from transaction_table tt;

否则,您可以创建一个感兴趣的月份列表,然后在where子句中进行比较:

select months.*
from (select to_date('2013-01-01', 'YYYY-MM-DD') as firstday, to_date('2013-01-31', 'YYYY-MM-DD') as lastday from dual union all
      select to_date('2013-02-01', 'YYYY-MM-DD') as firstday, to_date('2013-02-28', 'YYYY-MM-DD') as lastday
     ) as months
where exists (select 1
              from transaction_table tt
              where tt.date between months.firstday and months.lastday
             )

Usingexists应该强烈建议优化器使用索引。

于 2013-07-08T13:19:07.133 回答
0

您的要求只是查看每个月是否至少存在一个数据集。

那为什么我们不能试试这个,

select month
from transaction_table
group by month
HAVING COUNT(1) > 0
于 2013-07-08T14:53:10.810 回答
0

您可能会尝试从索引中获取单个值 - 这将取决于解释计划 - 但可能与此类似:

select distinct ( month ) from transaction_table 

另一种方法是使用触发器将月份保存在单独的表中 - 这种非规范化将大大加快您的查询速度。

于 2013-07-08T13:17:07.917 回答
0

我建议获取不同日期的列表,然后从中获取不同月份的列表。

SELECT DISTINCT MONTH(A.DATES) 
FROM (SELECT DISTINCT DATE AS DATES FROM TRANSACTION_TABLE) A

内部查询将使用 DATE 上的索引,只要它是日期字段而不是日期时间,它将每年在数据中仅返回 365 个单列行。外部查询可以将其转换为所需的月份列表。

于 2013-07-09T05:43:58.060 回答