【问题标题】:Oracle SQL TO_DATE and TO_TIMESTAMPOracle SQL TO_DATE 和 TO_TIMESTAMP
【发布时间】:2017-07-13 03:18:42
【问题描述】:

我在 Oracle SQL 中有两个等效的查询。

SELECT ... FROM TABLE WHERE timestamp = TO_DATE('2017-07-01', 'YYYY-MM-DD')

SELECT ... FROM TABLE WHERE 
timestamp >= TO_TIMESTAMP('2017-07-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') AND
timestamp < TO_TIMESTAMP('2017-07-02 00:00:00', 'YYYY-MM-DD HH24:MI:SS')

一般来说,我需要每天(自动)运行它,这样第一个查询就足以满足应用程序的需求。但是,对于前几次运行,我需要一些自定义日期时间边界,因此我可能会手动干预并改用第二个查询。

我观察到的是第一个跑得更快。在引擎盖下,真的是这样吗?性能差异是否足够显着?谁能解释一下?

【问题讨论】:

  • pl/sql 是一种过程语言(不同于 SQL),它与您的问题无关。
  • 这两个查询不等价。即使第二个查询可能检索到数千行,第一个查询也可能检索到很少的行(可能没有!)。您是否暗示在您的数据中时间戳始终具有等于 00:00:00 的时间部分,这使得两个查询等效? 可能知道这一点,但 Oracle 不读取值就无法知道它,因此即使这样,第一个查询也会比第二个查询快也就不足为奇了。是的,实际上这两个查询并不相同。
  • 另外,在第一个查询中,为什么要将时间戳与日期而不是时间戳进行比较?然后:为避免不必要的函数调用,您可以使用时间戳文字语法:... timestamp_column = (or &gt;= etc.) timestamp '2017-07-01 00:00:00'
  • @mathguy 是的,时间戳列的格式为2017-07-01 00:00:00.0
  • @menorah84,没有时间戳列没有格式。问题是,数据包含什么?所有记录上的时间是否都设置为精确的00:00:00.000000

标签: oracle datetime


【解决方案1】:

魔鬼在细节中。

1) 表中有多少条记录?

2) 满足多少条记录

timestamp = TO_DATE('2017-07-01', 'YYYY-MM-DD')

3) 满足多少条记录

timestamp >= TO_TIMESTAMP('2017-07-01 00:00:00', 'YYYY-MM-DD HH24:MI:SS') AND
timestamp < TO_TIMESTAMP('2017-07-02 00:00:00', 'YYYY-MM-DD HH24:MI:SS')

4) 表格是否收集了统计信息? timestamp 列有直方图统计吗?

5) 您在timestamp 列上有索引吗?或者它可能被时间戳(子)分区?

为表和索引发送 DDL 可能会更容易 - 这真的很有帮助。

假设您已为 timestamp 列编制索引,那么对于您要查找的第一个查询,它是一个值,在另一种情况下,它是一个值范围。因此,根据上面提到的统计信息和许多其他因素,Oracle 可以选择切换到全表扫描,例如,如果它认为第二个谓词返回更多的行以便直接读取表的成本更低。

我知道问题可能多于答案,但 Oracle 数据库非常灵活,而且随着灵活性而来的是复杂性。希望以上信息对您有所帮助。

此外,一个简单的解释计划、sqlplus autrotrace 或最佳情况 10053 trace 或 10046 跟踪可以更明确地回答那里发生的事情。

【讨论】:

  • 它们返回相同的行数。
猜你喜欢
  • 1970-01-01
  • 2018-06-17
  • 2020-09-02
  • 2018-04-23
  • 2017-09-14
  • 2014-02-01
  • 2015-07-31
  • 2020-03-01
  • 2011-10-27
相关资源
最近更新 更多