You can create a materialized view for this query:
CREATE MATERIALIZED VIEW v_address REFRESH FORCE ON COMMIT AS SELECT address_key FROM person_address WHERE person_key IN (person_list)
or create a temporary table and populate it:
CREATE GLOBAL TEMPORARY TABLE tt_address (VARCHAR2(50)); INSERT INTO tt_address SELECT address_key FROM person_address WHERE person_key IN (person_list)
but really, if you specified your person_key , then it will be okay to reuse the subquery.
Since you have 3 separate queries, you need your values to be visible to them anyway.
This means that you need to store these values somewhere, be it memory, a temporary table space, or a permanent table space.
But the values you need are already stored in person_address , all you need is their choice.
Using a 3 times subquery will include 12 index scans to extract the ROWID from the index in person_key tags and 12 table ROWID to retrieve the address_key from the table. Then, most likely, a HASH TABLE will be built over them.
This is a matter of microseconds.
Of course, a temporary table or materialized view will be a little more efficient, but changing the subquery time from 100 microseconds to 50 hardly worth the fact that the main queries can take minutes.
Quassnoi
source share