【发布时间】:2021-04-13 11:59:38
【问题描述】:
我想知道如何访问表中的日期列并将其用作另一个大容量表的日期过滤器。
我有以下查询,目前使用 sysdate,它会在 20 分钟内完成。
select a,b,datec, sum(c) from table1
where datec = sysdate - 1 group by a,b,datec
我正在尝试用另一个名为 table2 的表中的日期替换 sysdate。这是一个有 1600 行的小表,它只返回最新的周期完成日期(一个值),通常是 sysdate - 1 大部分日期,假期除外。table1 有数百万行。
我尝试了以下查询以获取过滤条件中的日期值:
select a,b,datec, sum(c) from table1 t1, table2 t2 where t1.datec = t2.pdate and t2.prcnm = 'TC' group by a,b,datec
select a,b,datec, sum(c) from table1 t1 inner join table2 t2 on datec = t2.pdate and t2.prcnm = 'TC' group by a,b,datec
select a,b,datec, sum(c) from table1 t1 where t1.datec = (SELECT t2.date FROM table2 t2 WHERE prcnm = 'TC') group by a,b,datec
上述查询耗时过长,最终失败并显示此错误消息 - “并行查询服务器意外死亡”
我想知道如何从 table2 获取日期并在 table1 中使用它而不会遇到性能问题。我无法查看计划,因为 table1 是一个视图,我无权访问底层对象。
谢谢。
【问题讨论】:
-
在第二个查询中,为什么你有一个 outer 连接?这与其他查询(您的原始查询或两个替代查询)不对应。除此之外,我怀疑优化器正在尝试做一些花哨的事情,当你想要的是它从你的代码的最后一个版本中的子查询中计算日期,然后完全按照它使用它的方式使用该日期在您当前的查询中(基于 sysdate)。但是,首先要问一个问题:子查询(来自
t2)是否有可能返回恰好一个值以外的任何值? -
我应该添加 - 您可以尝试的一件事是
where子句中子查询中的/*+ no_unnest */提示(以防止优化器执行我在前面提到的“花哨的事情”评论)。 -
它不会返回多个值,也不会返回多个值。我还通过使用该条件直接查询 t2 来仔细检查它确实只返回一个值。对不起,它不应该离开连接。让我更正它。我认为即使我将其作为内部连接也可能无济于事。我什至无法使用任何这些选项返回 10 行。让我试试 no_unnest 选项,然后告诉你。感谢您的投入。
-
我试过这个 - select a,b,datec, sum(c) from table1 t1 where t1.datec = (SELECT /*+ no_unnest qb_name(subq1) */ t2.date FROM table2 t2 WHERE prcnm = 'TC') group by a,b,datec - 没有任何区别..他们的查询继续运行。我应该以不同的方式使用它还是有任何其他提示可以帮助解决这个问题?很奇怪,查询甚至没有返回十行.. 它可能是 Oracle 中的错误或类似的东西吗?
-
您的组织期望您在不访问解释或执行计划的情况下调整查询是不合理的。这就像说,“让这个程序在不知道算法或数据结构的情况下快速运行。”我们可以做出疯狂的猜测,比如尝试添加
/*+ no_parallel */或where rownum = 1,但如果没有计划,我们不知道发生了什么以及为什么会起作用。尽管您显然已经在这个问题上付出了努力,但对其他人没有用处。
标签: sql database oracle query-optimization sql-tuning