我正在Oracle中修改一个查询,其中需要上月的数据.目前,查询有一个where子句,其中包含以下内容:

...
...
...
WHERE cust_dt BETWEEN TO_DATE('05-01-2022','mm-dd-yyyy) AND TO_DATE('05-31-2022', 'mm-dd-yyyy')

我正在修改查询,以便不需要每月手动更改开始日期和结束日期来运行查询.在做了一些研究之后,我得出了以下结论:

...
...
...
WHERE TO_CHAR(cust_dt, 'MM-YYYY') = TO_CHAR(add_months(sysdate, -1), 'MM-YYYY')

我得到的结果是我想要的,但我很好奇,在给定更 Big Data 集的情况下,哪个查询的性能更好.我在网上看到的所有帖子都是在两者之间使用的,所以我想知道这是否有什么原因.

就调优、测试、性能等方面而言,我是一个完全的新手.实际查询本身非常复杂,有几个连接,因此性能很重要.目前,我只有少量的测试数据可供处理,因此我只能尽我所能找到最佳结果.

回到我的问题上来,哪一个查询最好?是使用BETWEEN还是使用TO\u CHAR?

推荐答案

WHERE TO_CHAR(cust_dt, 'MM-YYYY') = TO_CHAR(add_months(sysdate, -1), 'MM-YYYY')

不会在cust_dt列上使用索引;相反,您需要在TO_CHAR(cust_dt, 'MM-YYYY')的基础上创建一个单独的基于函数的索引

WHERE cust_dt BETWEEN TO_DATE('05-01-2022', 'mm-dd-yyyy')
                  AND TO_DATE('05-31-2022', 'mm-dd-yyyy')

将在cust_dt列上使用索引.

然而,在Oracle中,DATE数据类型由7个字节组成,表示:世纪、世纪之年、月、日、小时、分钟和秒.It ALWAYS有这些组件(但通常用于访问数据库的客户端应用程序默认只显示日期组件,而不显示时间组件,但时间组件仍然存在).

这意味着您的查询将找到cust_dt介于2022-05-01 00:00:002022-05-31 00:00:00之间的值.当cust_dt介于2022-05-31 00:00:012022-05-31 23:59:59之间时,它将与值不匹配.

回到我的问题上来,哪一个查询最好?

也不

您需要(如果您正在硬编码日期):

WHERE cust_dt >= TO_DATE('05-01-2022', 'mm-dd-yyyy')
AND   cust_dt <  TO_DATE('06-01-2022', 'mm-dd-yyyy')

或者(如果您正在动态查找日期):

WHERE cust_dt >= ADD_MONTHS(TRUNC(SYSDATE, 'MM'), -1)
AND   cust_dt <  TRUNC(SYSDATE, 'MM')

它将使用cust_dt的索引,并匹配该月的整个范围.

db<>fiddle 100

Sql相关问答推荐

PostgreSQL:获取每家店铺收入最高的员工

如何以"% m—% d"格式对生日列表进行排序,以查找与今天最近的日期?

Postgres JSONB对象筛选

SQL查询每个客户的最新条目

在甲骨文中查找前一个星期一的S日期

对列进行排序后,基于两列删除重复行

如何根据行状态设置正确的标志

DB2 SQL查询结果多余数据

如何在 SQL Server 中解决这个复杂的窗口查询?

匹配 H[0-9][0-9] 但不匹配除字母 H 之外的任何字母

Postgresql:在链接表中判断相关表中插入值的条件

使用长 IN 子句的 SQL 优化

INSERT INTO 语法

根据不同日期标准分配组的逻辑

汇总具有连续日期范围的行

在SQL中实现表格数据透视类型报表

按公司和产品查询最近发票的平均价格的SQL查询

SQL中如何转置表格 UNPIVOT是唯一的 Select 吗?

如何优化仅返回符合条件的三条记录的查询?

如何在 DAX 中通过 Window 函数应用订单