我在Oracle中有一个按时间戳列划分的每月分区表。该表包含2019年历史记录数据中的> 10亿行。现在,我想过滤该表以获取特定日期有关HH24:MI:SS
部分的所有结果。
我面临的问题(#1)是,当使用TO_CHAR(TIMESTAMPCOLUMN, 'YYYY-MM-DD')
时,最近几个月查询的运行时间增加了。示例:
SELECT * FROM BIG_PART_TABLE WHERE TO_CHAR(TIMESTAMPCOLUMN, 'YYYY-MM-DD') = '2019-01-01' -- 3 sec
SELECT * FROM BIG_PART_TABLE WHERE TO_CHAR(TIMESTAMPCOLUMN, 'YYYY-MM-DD') = '2019-02-01' -- 6 sec
SELECT * FROM BIG_PART_TABLE WHERE TO_CHAR(TIMESTAMPCOLUMN, 'YYYY-MM-DD') = '2019-12-01' -- 36 sec
所以我摆脱了TO_CHAR
并开始这样过滤:
SELECT * FROM BIG_PART_TABLE WHERE TIMESTAMPCOLUMN BETWEEN DATE '2019-01-01' AND DATE '2019-01-02' -- 0.032 sec
SELECT * FROM BIG_PART_TABLE WHERE TIMESTAMPCOLUMN BETWEEN DATE '2019-12-01' AND DATE '2019-12-02' -- 0.031 sec
问题(#2)是我懒于编写BETWEEN
子句,除了它增加了错误机会的事实。
最后,我真正想要的是一个有效的单个where子句来过滤我的表,例如:
SELECT * FROM BIG_PART_TABLE WHERE TIMESTAMPCOLUMN = DATE '2019-01-01'
感谢所有人。
正确的方法是不要在日期列上使用日期函数-这样的函数使查询不可SARGable,这意味着它无法利用日期列上的索引。
我也建议使用半开间隔而不是between
:
WHERE
TIMESTAMPCOLUMN >= DATE '2019-01-01'
AND TIMESTAMPCOLUMN < DATE '2019-01-02'
[BETWEEN
在两端都是包容性的,因此您的表达式表示将过滤2019-01-02 00:00:00
上的时间戳,而这很可能不是您想要的。