【问题标题】:How to select first of the month from date field without TRUNC?如何在没有 TRUNC 的情况下从日期字段中选择月份的第一天?
【发布时间】:2017-01-28 21:52:05
【问题描述】:

有没有办法在不使用 trunc 函数的情况下从日期字段中选择月份的第一天?这让我的查询速度太慢了。我在 where 子句中有这样的:

WHERE trunc(DATE_FIELD, 'MM') = :v_Month 

查询在没有 trunc 函数的情况下运行 4 秒,但返回的数据集不完整。使用 trunc 函数将返回所有数据,但查询将需要 20 多分钟才能运行。

DATE_FIELD 一个月有很多天,但我只需要每月的第一天来记录每条记录。因此,如果 DATE_FIELD = 14/09/2016,我需要以某种方式获得 01/09/2016 但不使用 trunc。

这可能吗?

更新:

从代码中删除了 to_date()。这是一个错误,并没有在实际的完整查询中使用。

【问题讨论】:

  • 提防asking about your attempted solution rather than your actual problem。或许您可以提供更多关于降低查询速度的详细信息,例如显示两个查询的解释计划。
  • 请发布完整的查询并将:v_Month 替换为一个值。可能还有另一种优化方法...
  • 您在 DATE_FIELD 上使用 to_date()。仅当 DATE_FIELD 是字符串字段(varchar2 或类似字段)而不是日期字段时,这才有意义。如果是这样,您无能为力;您正在为将日期存储在错误的数据类型中而付出代价。如果实际上 DATE_FIELD 是日期数据类型,请使用提供的答案中的解决方案。

标签: oracle date truncate


【解决方案1】:

还有其他方法可以获取日期的第一天。但这些方法不会更有效。几乎可以肯定,问题的根源在于date_field 上有一个索引。当您使用date_field 而不对其进行任何函数调用时,Oracle 可以使用该索引并且您的查询是有效的。但是,一旦您在date_field 周围进行任何函数调用,Oracle 就不能再使用该索引,因此您会遇到效率低得多的查询计划。问题不在于 trunc 很慢,问题在于将任何函数调用放在索引列上会阻止使用该索引。

鉴于此,您有两种选择

  1. trunc(date_field, 'MM') 上创建一个基于函数的索引并保持查询不变。
  2. 重新制定查询,以便在没有函数的情况下对 date_field 有条件

类似

where date_field >= :v_Month
  and date_field <  add_months(:v_Month,1)

【讨论】:

  • @mathguy - 最初的问题是“如何在不使用trunc 的情况下截断”,并解释说trunc 太慢了。我是说还有其他截断日期的方法,但它们不会解决性能问题,因为性能问题不是 trunc 很慢,而是它阻止了查询使用索引。
  • 对不起,我已经删除了我的评论,因为我意识到了这一点。
  • 同时,我注意到我在对原始问题的评论中添加了什么。如果 DATE_FIELD 是一个日期,那么将它包装在 to_date 中已经会导致问题和执行缓慢,不管其他任何事情。如果它是一个字符串字段,这些解决方案都不起作用,唉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-07
  • 1970-01-01
  • 2013-06-07
  • 2011-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多