简体   繁体   English

多个分区子查询的性能

[英]Performance for multiple partitioned subqueries

I have a database with one main table and multiple history/log tables that stores the evolution over time of properties of some rows of main table.我有一个数据库,其中包含一个主表和多个历史/日志表,用于存储主表某些行的属性随时间的演变。 These properties are not stored on the main table itself, but must be queried from the relevant history/log table.这些属性不存储在主表本身,而是必须从相关的历史/日志表中查询。 All these tables are big (on the order of gigabytes).所有这些表都很大(大约千兆字节)。

I want to dump the whole main table and join the last entry of all the history/log tables.我想转储整个主表并加入所有历史/日志表的最后一个条目。

Currently I do it via subqueries as follows:目前我通过子查询来做到这一点,如下所示:

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 ...

The problem is that this is very slow.问题是这非常慢。 Is there a faster solution to this problem?这个问题有更快的解决方案吗?

I am only allowed to perform read-only queries on this database: I can not make any changes to it.我只能对此数据库执行只读查询:我无法对其进行任何更改。

In actual Oracle versions it's usually better to use laterals/CROSS APPLY, because CBO (oracle cost-based optimizer) can transform them (DCL - lateral view decorrelation transformation) and use optimal join method depending on your circumstances/conditions (table statistics, cardinality, etc).在实际的 Oracle 版本中,通常最好使用laterals/CROSS APPLY,因为 CBO(基于 Oracle 成本的优化器)可以转换它们(DCL - lateral view decorrelation转换)并根据您的情况/条件(表统计、基数)使用最佳连接方法, 等等)。

So it would be something like this:所以它会是这样的:

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.附注。 You haven't specified your oracle version, so my answer is for Oracle 12+你还没有指定你的 oracle 版本,所以我的回答是针对 Oracle 12+

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM