如何在oracle的多个select中避免使用相同的子查询?

6 sql oracle

这是使用相同子查询的三个不同选择.如何使用子查询结果而不是再次执行子查询.

SELECT  *
FROM    Address
WHERE   address_key IN
        (
        SELECT  address_key
        FROM    person_address
        WHERE   peson_key IN (person_list)
        );   -- person_list := '1,2,3,4'

SELECT  *
FROM    Phone 
WHERE   phone_key IN
        (
        SELECT  address_key
        FROM    person_address
        WHERE   peson_key IN (person_list)
        );

SELECT  *
FROM    Email
WHERE   address_key IN
        (
        SELECT  address_key
        FROM    person_address
        WHERE   peson_key IN (person_list)
        );
Run Code Online (Sandbox Code Playgroud)

Qua*_*noi 6

您可以为此查询创建物化视图:

CREATE MATERIALIZED VIEW v_address
REFRESH FORCE ON COMMIT
AS
SELECT  address_key
FROM    person_address
WHERE   person_key IN (person_list)
Run Code Online (Sandbox Code Playgroud)

,或创建一个临时表并填充它:

CREATE GLOBAL TEMPORARY TABLE tt_address (VARCHAR2(50));

INSERT
INTO   tt_address
SELECT  address_key
FROM    person_address
WHERE   person_key IN (person_list)
Run Code Online (Sandbox Code Playgroud)

但是,实际上,如果你索引你的person_key,那么重用子查询是可以的.

由于您有3单独的查询,因此您需要以某种方式显示您的值.

这意味着您需要将这些值存储在某处,无论是内存,临时表空间还是永久表空间.

但是你需要的值已经存储在了person_address,你只需要获取它们.

使用子查询3时间将涉及12索引扫描以ROWID从索引person_key12ROWID查找中获取address_key,以从表中获取.然后很可能HASH TABLE会建立在他们之上.

这是微秒的问题.

当然,临时表或物化视图会更高效,但是将子查询时间从100微秒更改50为几乎不值得,只要主查询可能需要几分钟.


Bri*_*ian 6

使用with子句.我没有重新创建您的确切示例问题,但可以在WITH子句中放入任意数量的重复子查询,然后在查询中引用.

WITH  address_keys as (
        SELECT  address_key
        FROM    person_address
        WHERE   peson_key IN (person_list)
        )
Select * from table1, table2, address_keys
where table1.address_key = address_keys.address_key
and table2.address_key = address_keys.address_key
Run Code Online (Sandbox Code Playgroud)