多个分区子查询的性能

问题描述

我有一个包含一个主表和多个历史/日志表的数据库,该数据库存储主表某些行的属性随时间的演变。这些属性未存储在主表本身上,但必须从相关的历史记录/日志表中查询。所有这些表都很大(大约千兆字节)。

我想转储整个主表并加入所有历史记录/日志表的最后一个条目。

目前,我通过以下子查询来做到这一点:

WITH
  foo AS (
    SELECT
      ROW_NUMBER() OVER (PARTITION BY itemid ORDER BY date DESC) AS rownumber,...
    FROM table1),bar AS (
    SELECT
      ROW_NUMBER() OVER (PARTITION BY itemid ORDER BY date DESC) AS rownumber,...
    FROM table2)
SELECT
  ...
FROM maintable mt
JOIN foo foo ON foo.itemid = mt.itemid AND foo.rownumber = 1
JOIN bar bar ON foo.itemid = mt.itemid AND bar.rownumber = 1
WHERE ...

问题是,这非常慢。有更快的解决方案吗?

仅允许我对此数据库执行只读查询:我无法对其进行任何更改。

解决方法

在实际的Oracle版本中,通常最好使用侧向/交叉应用,因为CBO(基于Oracle成本的优化器)可以对其进行转换(DCL-lateral view decorrelation转换)并根据您的情况/条件使用最佳联接方法(表格统计信息,基数等)。

所以会是这样:

SELECT
  ...
FROM maintable mt
CROSS APPLY (
      SELECT *
      FROM table1
      WHERE table1.itemid = mt.itemid
      ORDER BY date DESC
      fetch first 1 row only
      )
CROSS APPLY (
      SELECT *
      FROM table2
      WHERE table2.itemid = mt.itemid
      ORDER BY date DESC
      fetch first 1 row only
      )
WHERE ...

PS。您尚未指定oracle版本,所以我的答案是针对Oracle 12 +