Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, William.

Asked: December 05, 2005 - 2:37 am UTC

Last updated: March 10, 2006 - 8:26 pm UTC

Version: 9.2.0.7

Viewed 10K+ times! This question is

You Asked

It is possible to reduce the access to external table down to 1 time?

CREATE OR REPLACE DIRECTORY "BDUMP_DIR" AS 'c:\oracle\admin\dev92\bdump\'
/

CREATE TABLE "DBA_SUPPORT"."ALERT_LOG"
( "LINE1" VARCHAR2(4000)
)
ORGANIZATION EXTERNAL
( TYPE ORACLE_LOADER
DEFAULT DIRECTORY "BDUMP_DIR"
ACCESS PARAMETERS
( records delimited by newline fields missing field values are null )
LOCATION
( 'alert_dev92.log'
)
)
/

with
a as (select rownum line#, a.* from alert_log a ),
s as (select * from a where a.line1 like 'ORA-%')
select distinct a.*
from a, s
where a.line# between s.line# - 5 and s.line#
order by a.line#
/

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (UNIQUE)
2 1 NESTED LOOPS
3 2 VIEW
4 3 COUNT
5 4 EXTERNAL TABLE ACCESS (FULL) OF 'ALERT_LOG'
6 2 VIEW
7 6 COUNT
8 7 EXTERNAL TABLE ACCESS (FULL) OF 'ALERT_LOG'




Statistics
----------------------------------------------------------
31 recursive calls
0 db block gets
535 consistent gets
0 physical reads
0 redo size
28334 bytes sent via SQL*Net to client
873 bytes received via SQL*Net from client
36 SQL*Net roundtrips to/from client
3 sorts (memory)
0 sorts (disk)
512 rows processed


Best regards,
William


and Tom said...

two approaches:

ops$tkyte@ORA9IR2> set autotrace traceonly explain
ops$tkyte@ORA9IR2> with
2 a as (select /*+ MATERIALIZE */ rownum line#, a.* from alert_log a ),
3 s as (select * from a where a.line1 like 'ORA-%')
4 select distinct a.*
5 from a, s
6 where a.line# between s.line# - 5 and s.line#
7 order by a.line#
8 /

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 2 RECURSIVE EXECUTION OF 'SYS_LE_2_0'
2 0 TEMP TABLE TRANSFORMATION
3 2 SORT (UNIQUE)
4 3 NESTED LOOPS
5 4 VIEW
6 5 TABLE ACCESS (FULL) OF 'SYS_TEMP_0FD9D660B_127C20'
7 4 VIEW
8 7 TABLE ACCESS (FULL) OF 'SYS_TEMP_0FD9D660B_127C20'



ops$tkyte@ORA9IR2> select r, line1
2 from (select r, line1,
3 lead(line1,1) over (order by r) next1,
4 lead(line1,2) over (order by r) next2,
5 lead(line1,3) over (order by r) next3,
6 lead(line1,4) over (order by r) next4,
7 lead(line1,5) over (order by r) next5
8 from (select line1, rownum r from alert_log)
9 )
10 where line1 like 'ORA-%'
11 or next1 like 'ORA-%'
12 or next2 like 'ORA-%'
13 or next3 like 'ORA-%'
14 or next4 like 'ORA-%'
15 or next5 like 'ORA-%'
16 /

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 VIEW
2 1 WINDOW (SORT)
3 2 VIEW
4 3 COUNT
5 4 EXTERNAL TABLE ACCESS (FULL) OF 'ALERT_LOG'



ops$tkyte@ORA9IR2> set autotrace off


Rating

  (17 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

/*+ MATERIALIZE */

Kim Berg Hansen, December 06, 2005 - 9:14 am UTC

Hi, Tom

That hint (/*+ MATERIALIZE */) is new to me. Is it documented?

I can't find it in the list of hints in the 10g docs - but maybe it's just because I'm nearsighted :-)

Is it an alternative method of using "where rownum > 0" or something similar to force materializing an inline view?


Thanks for your help as always...


Tom Kyte
December 06, 2005 - 9:47 am UTC

it is not. (Jonathan Lewis is a proponent of materialize over the rownum > 0 'trick' I use sometimes)

it is like "where rownum > 0"

semi-documented hints

Padders, December 06, 2005 - 9:30 am UTC

While on the subject of hints (see how I did that), can you clarify the purpose and mechanism of the /*+ NESTED_TABLE_FAST_INSERT */ hint which is referred to in the 10g documentation for DBMS_FREQUENT_ITEMSET?

"If you want to use an insert statement to load frequent itemsets into a nested table, it is better to use the NESTED_TABLE_FAST_INSERT hint for performance:

CREATE TABLE fq_nt (coll FI_VARCHAR_NT) NESTED TABLE coll STORE AS
coll_nest;
INSERT /*+ NESTED_TABLE_FAST_INSERT */ INTO fq_nt
SELECT cast(itemset as FI_VARCHAR_NT)
FROM table(DBMS_FREQUENT_ITEMSET.FI_TRANSACTIONAL(
cursor(SELECT tid, iid FROM tranx_table_in), 0.6, 2, 5,
NULL, NULL));"

Tom Kyte
December 06, 2005 - 2:40 pm UTC

it appears it performs an array insert of the the nested table instead of slow by slow processing.

Very useful

William Lai, December 06, 2005 - 9:30 pm UTC

I think I will use the your second method.

my original method runtime: ~60sec
your method 1 runtime: ~31sec
your method 2 runtime: ~27sec

BTW, where can I find the documentation about the MATERIALIZE hint?

Thanks

Tom Kyte
December 07, 2005 - 1:51 am UTC

it is not currently documented.

line number of records in external table

Jay, December 07, 2005 - 11:34 am UTC

In answer to the original question, rownum has been used to number the lines in the file. For this solution to work correctly, rownum value should match the actual line number of each line in the file. Is this a deterministic way to get the position of a line in the file ? If it is deterministic, is it documented anywhere ?

Tom Kyte
December 08, 2005 - 1:20 am UTC

it is not documented.

Using rownum as the line number of lines in external table

Jay, December 08, 2005 - 12:47 pm UTC

1. Is it a good practice to use rownum as the line number of lines in an external table. Even though results might indicate that rownum matches the line number in current versions of Oracle, since it is not documented, Oracle might treat external tables like heap tables in future versions resulting in rownum no longer matching the line number

2. If the external table is accessed in parallel (for files with fixed width records), then rownum may not reflect the line number even in current versions of Oracle



Tom Kyte
December 09, 2005 - 1:13 am UTC

in a serial query (no parallel query), i see no issues - however, you have a point, so... here is perhaps a better approach:


CREATE TABLE "ALERT_LOG"
( "LINE1" VARCHAR2(4000),
r number

)
ORGANIZATION EXTERNAL
( TYPE ORACLE_LOADER
DEFAULT DIRECTORY "BDUMP_DIR"
ACCESS PARAMETERS
( records delimited by newline fields missing field values are null
( line1 position(1:4000), r RECNUM ) )
LOCATION
( 'alert_ora10gr2.log'
)
)
/
column line1 format a50
set autotrace on
select r, line1
from (select r, line1,
lead(line1,1) over (order by r) next1,
lead(line1,2) over (order by r) next2,
lead(line1,3) over (order by r) next3,
lead(line1,4) over (order by r) next4,
lead(line1,5) over (order by r) next5
from alert_log
)
where line1 like 'ORA-%'
or next1 like 'ORA-%'
or next2 like 'ORA-%'
or next3 like 'ORA-%'
or next4 like 'ORA-%'
or next5 like 'ORA-%'
/


RECNUM - undocumented for external table usage ?

Jay, December 09, 2005 - 12:27 pm UTC

Thanks for the alternative approach to get the line number of the records in the external table using RECNUM.

Searched the 9iR2 and 10gR2 DB utilities guide in the external table section - but could not find any mention of RECNUM.

Is the use of RECNUM as external table field datatype undocumented ?

If it is indeed undocumented - which is the lesser of 2 evils - use of rownum or RECNUM to get the line number ?

P.S: Tested in 9iR2 and RECNUM does indeed returns the line number of the records in an external table


Tom Kyte
December 09, 2005 - 1:14 pm UTC

MATERIALIZE Hint

A reader, December 10, 2005 - 1:58 am UTC

Hi Tom,

If materialize hint is undocumented, then we shouldn't be using it. Right......?

Tom Kyte
December 10, 2005 - 5:22 am UTC

up to you - as with all undocumented things. I do not, I use the technique I used for the second query.

RECNUM usage as an external table field datatype

Jay, December 10, 2005 - 12:52 pm UTC

If RECNUM can be used as an external table field datatype (even though currently undocumented) - don't you think this should be logged as a documentation bug ?
Otherwise how would anyone know that RECNUM can be used, since what can be carried over from "sqlldr" is also not documented.

Tom Kyte
December 11, 2005 - 2:59 am UTC

it is documented - external tables support most all of the sqlldr constructs.

Also, you can see it from external_table = generate_only


but yes, I'll file a doc bug to get it added specifically to the external table section.

LOAD DATA
INFILE *
INTO TABLE DEPT
replace
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
(DNAME, LOC, deptno recnum)
BEGINDATA
RESEARCH,"SARATOGA"
ACCOUNTING",CLEVELAND


$ sqlldr / test.ctl external_table=generate_only

CREATE TABLE "SYS_SQLLDR_X_EXT_DEPT"
(
DNAME VARCHAR2(14),
LOC VARCHAR2(13),
DEPTNO NUMBER
)
ORGANIZATION external
(
TYPE oracle_loader
DEFAULT DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
ACCESS PARAMETERS
(
RECORDS DELIMITED BY NEWLINE CHARACTERSET US7ASCII
BADFILE 'SYS_SQLLDR_XT_TMPDIR_00000':'test.bad'
LOGFILE 'test.log_xt'
READSIZE 1048576
SKIP 7
FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED BY '"' LDRTRIM
REJECT ROWS WITH ALL NULL FIELDS
(
DNAME CHAR(255)
TERMINATED BY "," OPTIONALLY ENCLOSED BY '"',
LOC CHAR(255)
TERMINATED BY "," OPTIONALLY ENCLOSED BY '"',
DEPTNO RECNUM
)
)
location
(
'test.ctl'
)
)REJECT LIMIT UNLIMITED



Maybe materialize hint is undocumented for a good reason?

Andrew, January 20, 2006 - 9:50 am UTC


the materialize hint seems to have a dependency to global names.
can you explain this?

this well intentioned design attempted to have one copy of a package of business gic routines the functions needed to be called in views across dblinks. some of these routines take no arguments and return not-often-changed values. the functions take some time to execute. so when selected in a view it was desired to call them once for the view and not for every row. I know there are much better ways to accomplish this - syscontext, but they weren't ready for that. so here is an example of my attempt to get this done.

--on system 1
set autotrace trace
set timing on

create or replace package foo as
function bar return number;
end;
/

show errors

create or replace package body foo as
function bar return number is
begin
dbms_lock.sleep(1);
return to_number(to_char(sysdate,'YYYY'));
end bar;
end foo;
/

show errors

create or replace view foo_a as
with a as (select foo.bar bar from dual)
select a.bar foo_bar, object_name from user_objects,a where rownum < 10;

select * from foo_a;
--works

create or replace view foo_a as
with a as (select /*+MATERIALIZE*/foo.bar bar from dual)
select a.bar foo_bar, object_name from user_objects,a where rownum < 10;

select * from foo_a;
--works

-- global names is set to false
--on system 2
set autotrace trace
set timing on
select foo.bar@sys1 from dual;
-- works

create or replace view foo_a as
with a as (select foo.bar@sys1 bar from dual)
select a.bar foo_bar, object_name from user_objects,a where rownum < 10;
--works

select * from foo_a;
--works

create or replace view foo_a as
with a as (select /*+MATERIALIZE*/foo.bar@sys1 bar from dual)
select a.bar foo_bar, object_name from user_objects,a where rownum < 10;

--ORA-02069: global_names parameter must be set to TRUE for this operation



Tom Kyte
January 20, 2006 - 10:41 am UTC

... this well intentioned design attempted to have one copy of a package of business
gic routines the functions needed to be called in views across dblinks. ...


I agree with the term "well intentioned" since intentions can be good even if the implementation is not. No way I would do that for performance and availablility reasons - 0% chance.

As materialize is one of those undocumented hints, all I can say is to not use it in this case.

but, you can just rely on scalar subquery caching.


select (select foo.bar@sys1 from dual) bar, object_name
from user_objects;


that should cache the scalar subquery and execute it once per query.

another reason to not materialize ...

Andrew, January 20, 2006 - 10:05 am UTC

when a materialize hinted view is granted to another schema in the same instance this is what I get.


create or replace package foo as
function bar return number;
end;
/

show errors

create or replace package body foo as
function bar return number is
begin
dbms_lock.sleep(1);
return to_number(to_char(sysdate,'YYYY'));
end bar;
end foo;
/

show errors


create or replace view foo_a as
with a as (select /*+MATERIALIZE*/foo.bar bar from dual)
select a.bar foo_bar, object_name from user_objects,a where rownum < 10;

grant select on foo_a to user2;

--connect user2

DMS-DM> select * from user1.foo_a;
select * from user1.foo_a
*
ERROR at line 1:
ORA-03001: unimplemented feature





rownum > 0 does not work with updates ?

Rahul, February 02, 2006 - 1:44 pm UTC

A situation where I couldn't get rownum > 0 to work, but the materialize hint seems to work

I have an update stmt, and the updated data comes from a subquery. I wanted to materialize the subquery. Couldn't get rownum > 0 to work, but the materialize hint seems to work (after a lot of help from here - </code> http://dizwell.com/main/component/option,com_smf/Itemid,114/topic,168.0 <code>):

------------------------------------------------------------
-- rownum > 0
------------------------------------------------------------
UPDATE rahul_temp_sr s
SET site_key_qy =
(WITH q1 AS
(SELECT COUNT (DISTINCT (site_key)) qy,
a2s.sr_id
FROM rahul_temp_acct a,
rahul_temp_acct2sr a2s
WHERE a.acct_id = a2s.acct_id
AND ROWNUM >= 0
GROUP BY a2s.sr_id)
SELECT x.qy
FROM q1 x
WHERE x.sr_id = s.sr_id)

--------------------------------------------------------
| Id | Operation | Name |
--------------------------------------------------------
| 0 | UPDATE STATEMENT | |
| 1 | UPDATE | RAHUL_TEMP_SR |
| 2 | TABLE ACCESS FULL | RAHUL_TEMP_SR |
| 3 | VIEW | |
| 4 | SORT GROUP BY | |
| 5 | COUNT | |
| 6 | FILTER | |
| 7 | MERGE JOIN | |
| 8 | SORT JOIN | |
| 9 | TABLE ACCESS FULL| RAHUL_TEMP_ACCT2SR |
| 10 | SORT JOIN | |
| 11 | TABLE ACCESS FULL| RAHUL_TEMP_ACCT |
--------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

3 - filter("X"."SR_ID"=:B1)
6 - filter(ROWNUM>=0)
10 - access("A"."ACCT_ID"="A2S"."ACCT_ID")
filter("A"."ACCT_ID"="A2S"."ACCT_ID")

Note: cpu costing is off

------------------------------------------------------------
-- with materialize hint
------------------------------------------------------------
UPDATE rahul_temp_sr s
SET site_key_qy =
(WITH q1 AS
(SELECT /*+ materialize */
COUNT (DISTINCT (site_key)) qy,
a2s.sr_id
FROM rahul_temp_acct a,
rahul_temp_acct2sr a2s
WHERE a.acct_id = a2s.acct_id
-- AND ROWNUM >= 0
GROUP BY a2s.sr_id)
SELECT x.qy
FROM q1 x
WHERE x.sr_id = s.sr_id)

--------------------------------------------------------------------
| Id | Operation | Name |
--------------------------------------------------------------------
| 0 | UPDATE STATEMENT | |
| 1 | UPDATE | RAHUL_TEMP_SR |
| 2 | TABLE ACCESS FULL | RAHUL_TEMP_SR |
| 4 | TEMP TABLE TRANSFORMATION | |
| 3 | RECURSIVE EXECUTION | SYS_LE_4_0 |
| 0 | INSERT STATEMENT | |
| 1 | LOAD AS SELECT | |
| 2 | SORT GROUP BY | |
| 3 | MERGE JOIN | |
| 4 | SORT JOIN | |
| 5 | TABLE ACCESS FULL | RAHUL_TEMP_ACCT2SR |
| 6 | SORT JOIN | |
| 7 | TABLE ACCESS FULL | RAHUL_TEMP_ACCT |
| 5 | VIEW | |
| 6 | TABLE ACCESS FULL | SYS_TEMP_0FD9D660C_10B3AF26 |
--------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

6 - access("A"."ACCT_ID"="A2S"."ACCT_ID")
filter("A"."ACCT_ID"="A2S"."ACCT_ID")
5 - filter("X"."SR_ID"=:B1)

Note: cpu costing is off


forgot to mention version above ...

Rahul, February 06, 2006 - 8:40 am UTC

Running 9i on HP-UX
Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production


Tom Kyte
February 07, 2006 - 12:49 am UTC

when I have to hit page down lots of times to read the entire thing, I usually have to skip it here - too large to get into in a review/followup.

but it seems you have found a working solution?

(and you didn't show that it did not materialize the subquery - why do you think the subquery was executed more than once? I don't have a test case to play with - don't know your data - sort of hard to work with)

read consistent line#

Ray DeBruyn, February 08, 2006 - 2:22 pm UTC

Hi Tom,

I am replacing a data warehouse load process and plan to use external tables. Not all data is loaded and a user may need to get to see the original line from the file. My plan is to store the line# and, on the rare occasion the user needs to see the original, call a procedure supplying the line# to retrieve it. One file could be 600K records with 300 plus attributes and many files are loaded per month.

You have mentioned that using rownum as the line# (with external tables) is not documented and I was wondering if I am better off reading the file into a CLOB and parsing it in PL code. This should guarantee that the first line parsed is the first line.

I was doing an insert /*+ append */ into mytable selecting from a pipelined table function. This funtion selected from the external table, datatyped, looked up foreign keys (...) and piped rows.

My change would be to have the function open the CLOB, parse, datatype, look up foreign keys and pipe rows. Do you think I would take a performance hit with this plan?

Tom Kyte
February 09, 2006 - 4:52 am UTC

I would use the recnum myself.

up to you at this point.

Optimize External Table Access

charles lanfair, February 09, 2006 - 3:24 pm UTC

Browsing at lunch, have/am using external tables. Title caught my eye, thanks.
Targeting alert logs very useful and tuning the access, sorry to admit using external tables when I got the rows I was done - will apply more diligence.
What knocked me out - at the risk of confessing to not knowing it - was this:
"with
a as (select rownum line#, a.* from alert_log a ),
s as (select * from a where a.line1 like '% LOG_ARCHIVE_DEST_1%')
select distinct a.*...... "

I have never seen this construct 'with' before!
Where do I read more on this? Searching on 'with' gets a lot of unwanted prepostions. Thanks so much. CJL


Tom Kyte
February 10, 2006 - 11:40 am UTC

Re : rownum > 0 does not work with updates ?

Rahul, March 09, 2006 - 8:32 pm UTC

Tom, I did not paste the complete scripts since I thought it too large to be a followup too. The link I posted has the table creation, population scripts complete with a small picture of the data model at the original forum though :). Here are the relevant details:

We have a Many to Many relationship between Sales Resources and Accounts resolved into 3 tables. Accounts have an attribute "Site Key" which may be repeated for different accounts. We need to have a denormalised count of distinct site keys (of accounts) linked to a Sales Resource.

-- Create Tables
create table rahul_temp_sr
(sr_id varchar2(10),
site_key_qy number)
/

create table rahul_temp_acct
(acct_id varchar2(30),
site_key varchar2(14))
/

create table rahul_temp_acct2sr
(acct_id varchar2(30),
sr_id varchar2(10))
/

-- Populate data
insert into rahul_temp_sr
select l, 0 from (select level l from dual connect by level <= 15000)
/

insert /*+ append */ into rahul_temp_acct
select l, -l from (select level l from dual connect by level <= 10000000)

insert /*+ append */ into rahul_temp_acct2sr
select acct_id, mod(rownum,15000) + 1
from rahul_temp_acct

-- Create Constraints/Indexes
alter table rahul_temp_sr add constraint rahul_temp_sr_pk primary key (sr_id)
/
alter table rahul_temp_acct add constraint rahul_temp_acct_pk primary key (acct_id) novalidate
/
alter table rahul_temp_acct2sr add (constraint acct2sr_acct_fk foreign key (acct_id) references rahul_temp_acct(acct_id) novalidate,
constraint acct2sr_sr_fk foreign key (sr_id) references rahul_temp_sr(sr_id) novalidate)
/
create index rahul_temp_acct2sr_idx on rahul_temp_acct2sr(acct_id,sr_id)
/

-- Analyze
analyze table rahul_temp_sr compute statistics for table for all indexed columns for all indexes
/
analyze table rahul_temp_acct compute statistics for table for all indexed columns for all indexes
/
analyze table rahul_temp_acct2sr compute statistics for table for all indexed columns for all indexes
/


-- The update statement in question is:
UPDATE rahul_temp_sr s
SET site_key_qy =
(SELECT x.qy
FROM (SELECT COUNT (DISTINCT (site_key)) qy,
a2s.sr_id
FROM rahul_temp_acct a,
rahul_temp_acct2sr a2s
WHERE a.acct_id = a2s.acct_id
AND ROWNUM >= 0
GROUP BY a2s.sr_id) x
WHERE x.sr_id = s.sr_id)
/

I only realized that the subquery was not being materialized when I saw the repeated full table scans on the tables in the subquery while watching v$session_longops. After seeing that, I looked back at the plan and assumed that is how I was supposed to interpret the predicate information in the plan. Specifically: 3 - filter("X"."SR_ID"=:B1)

--------------------------------------------------------
| Id | Operation | Name |
--------------------------------------------------------
| 0 | UPDATE STATEMENT | |
| 1 | UPDATE | RAHUL_TEMP_SR |
| 2 | TABLE ACCESS FULL | RAHUL_TEMP_SR |
| 3 | VIEW | |
| 4 | SORT GROUP BY | |
| 5 | COUNT | |
| 6 | FILTER | |
| 7 | MERGE JOIN | |
| 8 | SORT JOIN | |
| 9 | TABLE ACCESS FULL| RAHUL_TEMP_ACCT2SR |
| 10 | SORT JOIN | |
| 11 | TABLE ACCESS FULL| RAHUL_TEMP_ACCT |
--------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

3 - filter("X"."SR_ID"=:B1)
6 - filter(ROWNUM>=0)
10 - access("A"."ACCT_ID"="A2S"."ACCT_ID")
filter("A"."ACCT_ID"="A2S"."ACCT_ID")




Tom Kyte
March 10, 2006 - 12:01 pm UTC

here, if you look at this:

UPDATE rahul_temp_sr s
SET site_key_qy =
(SELECT x.qy
FROM (SELECT COUNT (DISTINCT (site_key)) qy,
a2s.sr_id
FROM rahul_temp_acct a,
rahul_temp_acct2sr a2s
WHERE a.acct_id = a2s.acct_id
AND ROWNUM >= 0
GROUP BY a2s.sr_id) x
WHERE x.sr_id = s.sr_id)
/

you have what is known as a correlated subquery.

that inner query is logically executed once for every row in the outer query. Whether the rownum thing materialized or not - it would be run for every row in the outer query (since the INPUTS to it VARY for every row!!)

it did in fact "materialize it", it just has to do that for every single row!

Re : rownum > 0 ...

Rahul, March 10, 2006 - 12:40 pm UTC

The query where the rownum is applied is not correlated (thought the surrounding subquery is):

SELECT COUNT (DISTINCT (site_key)) qy,
a2s.sr_id
FROM rahul_temp_acct a,
rahul_temp_acct2sr a2s
WHERE a.acct_id = a2s.acct_id
AND ROWNUM >= 0
GROUP BY a2s.sr_id

When I use the materialize hint as follows, it actually does execute the innermost subquery only once (by creating a temporary table for the result set).

UPDATE rahul_temp_sr s
SET site_key_qy =
(WITH q1 AS
(SELECT /*+ materialize */
COUNT (DISTINCT (site_key)) qy,
a2s.sr_id
FROM rahul_temp_acct a,
rahul_temp_acct2sr a2s
WHERE a.acct_id = a2s.acct_id
GROUP BY a2s.sr_id)
SELECT x.qy
FROM q1 x
WHERE x.sr_id

Or am I getting this completely wrong and comparing apples to oranges.

Tom Kyte
March 10, 2006 - 8:26 pm UTC

that sort of makes it correlated then.

The entire subquery is the subquery. not tiny bits and pieces of it.

typo

Rahul, March 10, 2006 - 12:45 pm UTC

thought the surrounding subquery is
=
though the surrounding subquery is

More to Explore

Analytics

Analytic SQL got you confused? Check out Connor McDonald's complete video course.