Main Page | Report this Page
Computers Forum Index  »  Computer - Databases - Oracle (Server)  »  Temporary table use and the redo log...
Page 1 of 2    Goto page 1, 2  Next

Temporary table use and the redo log...

Author Message
codefragment at (no spam) googlemail.com...
Posted: Mon Sep 07, 2009 4:23 pm
Guest
Hi
I'm using a global (session) temporary table to break up a section
of a stored procedure that is needed in
a number of places. Always for use in a select.
If the database crashes, gets rolled back, anything, I don't care
about the contents of that
table. Especially -I don't want redo logs for it-. Is there any way I
can accomplish this?

From what I can see so far I should look into:
- unrecoverable
- insert /*+APPEND */ into temp_table select...
- possibly using a table variable

Nologging is on by default for a tempory table but you still get some
logging

Am I on the right track?

thanks
 
codefragment at (no spam) googlemail.com...
Posted: Mon Sep 07, 2009 5:28 pm
Guest
Quote:
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1...http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1...

thanks for the reply, the links don't work for me though...
 
Mladen Gogala...
Posted: Mon Sep 07, 2009 5:57 pm
Guest
On Mon, 07 Sep 2009 09:23:31 -0700, codefragment at (no spam) googlemail.com wrote:

Quote:
Hi
I'm using a global (session) temporary table to break up a section
of a stored procedure that is needed in a number of places. Always for
use in a select.
If the database crashes, gets rolled back, anything, I don't care
about the contents of that
table. Especially -I don't want redo logs for it-. Is there any way I
can accomplish this?

From what I can see so far I should look into: - unrecoverable
- insert /*+APPEND */ into temp_table select... - possibly using a table
variable

Nologging is on by default for a tempory table but you still get some
logging

Am I on the right track?

thanks


The storage for temporary tables is allocated entirely from the temporary
tablespace. Blocks in a temporary tablespace are not proteced by redo so
nologging is on by default as you say. Even more than that, there is no
"current version" and "read consistent" version of the temporary blocks.
Temporary blocks are written from PGA to temporary tablespace in a way
very similar to what /*+ APPEND */ hint does. In other words, that hint is
for normal insert and has no visible effect on inserting into global
temporary tables. To verify that, you can run it with the event 10046,
level 12 and see that there are no visible differences in the trace file.




--
http://mgogala.freehostia.com
 
codefragment at (no spam) googlemail.com...
Posted: Mon Sep 07, 2009 7:56 pm
Guest
On 7 Sep, 20:22, Robert Klemme <shortcut... at (no spam) googlemail.com> wrote:
Quote:
On 07.09.2009 19:57, Mladen Gogala wrote:





On Mon, 07 Sep 2009 09:23:31 -0700, codefragm... at (no spam) googlemail.com wrote:

Hi
  I'm using a global (session) temporary table to break up a section
of a stored procedure that is needed in a number of places. Always for
use in a select.
  If the database crashes, gets rolled back, anything, I don't care
about the contents of that
table. Especially -I don't want redo logs for it-. Is there any way I
can accomplish this?

From what I can see so far I should look into: - unrecoverable
- insert /*+APPEND */ into temp_table select... - possibly using a table
variable

Nologging is on by default for a tempory table but you still get some
logging

Am I on the right track?

thanks

The storage for temporary tables is allocated entirely from the temporary
tablespace. Blocks in a temporary tablespace are not proteced by redo so
nologging is on by default as you say. Even more than that, there is no
"current version" and "read consistent" version of the temporary blocks..
Temporary blocks are written from PGA to temporary tablespace in a way
very similar to what /*+ APPEND */ hint does. In other words, that hint is
for normal insert and has no visible effect on inserting into global
temporary tables. To verify that, you can run it with the event 10046,
level 12 and see that there are no visible differences in the trace file.

But there is a bit of redo because of the undo:

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1....

(Hopefully that link works...)

Kind regards

        robert

--
remember.guy do |as, often| as.you_can - without endhttp://blog.rubybestpractices.com/- Hide quoted text -

- Show quoted text -

Its 'a little bit of undo' that seems to be my problem
From the asktom site:

Inserting 500 rows,

generates

3,297,752 bytes of redo generated for "insert into perm "...
66,488 bytes of redo generated for "insert into temp

So if you have a stored procedure that inserts 1000 rows when called
and is called 1000 times a minute
thats 132M a minute (66,488/500*1000*1000), 191G a day. Bearing in
mind this is temporary table I am
selecting from, I will never want to keep it.

How long should these logs persist from, what are common practices?
 
codefragment at (no spam) googlemail.com...
Posted: Mon Sep 07, 2009 7:57 pm
Guest
Quote:
The storage for temporary tables is allocated entirely from the temporary
tablespace.

Thanks for the reply. I'm probably missing something based on limited
understanding.

I can see on my Oracle database there are 3 redo log files, from some
reading it seems these are populated in turn
and these later populate archive files. Its those archive files I'm
looking at.

I created a script which using a cursor and a loop populated a
temporary table using 1 million inserts. I can see
the archive log files increasing as this happens in:

D:\oracle\product\10.1.0\flash_recovery_area\<oracle name>\ARCHIVELOG
\2009_09_07

The temporary table looks something like this:

CREATE GLOBAL TEMPORARY TABLE TP_TEMP
(
somecolumn INT,

) ON COMMIT PRESERVE ROWS;

We have perhaps 10 stored procedures that create the temp table and
then call 2 stored procedures to populate it
so that they can then do whatever they need to with the output.
Once the calling stored procedures are finished then the contents of
the temporary table can be discarded.

If what your saying is true then I didn't think those archive files
would be increasing?

Also using the /*+ APPEND */ hint did seem to make a difference,
those files weren't increasing, although in
retrospect I'm not not convinced it was a valid test, it did about 1
insert of 10,000 rows as I could only
call it once before I got some kind of error. I'll try it again
tomorrow

thanks for your replies, I appreciate it
 
Robert Klemme...
Posted: Mon Sep 07, 2009 8:35 pm
Guest
On 07.09.2009 18:23, codefragment at (no spam) googlemail.com wrote:
Quote:
Hi
I'm using a global (session) temporary table to break up a section
of a stored procedure that is needed in
a number of places. Always for use in a select.
If the database crashes, gets rolled back, anything, I don't care
about the contents of that
table. Especially -I don't want redo logs for it-. Is there any way I
can accomplish this?

From what I can see so far I should look into:
- unrecoverable
- insert /*+APPEND */ into temp_table select...
- possibly using a table variable

I suggest to also look into ON COMMIT DELETE ROWS.

Quote:
Nologging is on by default for a tempory table but you still get some
logging

Am I on the right track?

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:15826034070548#50549336675394
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:15826034070548#53994537734234

Cheers

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
codefragment at (no spam) googlemail.com...
Posted: Mon Sep 07, 2009 10:05 pm
Guest
Perhaps a table variable instead of a temporary table. Don't know much
about these so one to look into.
 
John Hurley...
Posted: Mon Sep 07, 2009 10:09 pm
Guest
On Sep 7, 3:57 pm, "codefragm... at (no spam) googlemail.com"
<codefragm... at (no spam) googlemail.com> wrote:

snip

Quote:
Thanks for the reply. I'm probably missing something based on limited
understanding.

I can see on my Oracle database there are 3 redo log files, from some
reading it seems these are populated in turn
and these later populate archive files. Its those archive files I'm
looking at.

If you are running in archivelog mode you probably want more than 3
online log files. Perhaps something like 10 ( your mileage may
vary ).

If you have 3 online logs and you are running something generating a
lot of log activity ... online 1 can fill up ... switching to online
2 ... it fills up ... switch to online 3 ... it fills up ... switch to
log 1 ... except it is still being archived ... oops ... everyone
waits.

Sizing of online logs and the number of them needs to be looked at in
a system running in archivelog mode.
 
Robert Klemme...
Posted: Mon Sep 07, 2009 11:20 pm
Guest
On 07.09.2009 19:28, codefragment at (no spam) googlemail.com wrote:
Quote:
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1...http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1...

thanks for the reply, the links don't work for me though...

Darn, sorry for that. You should find those entries by going to

http://asktom.oracle.com/

And searching for "global temporary redo".

Kind regards

robert


--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
Robert Klemme...
Posted: Mon Sep 07, 2009 11:22 pm
Guest
On 07.09.2009 19:57, Mladen Gogala wrote:
Quote:
On Mon, 07 Sep 2009 09:23:31 -0700, codefragment at (no spam) googlemail.com wrote:

Hi
I'm using a global (session) temporary table to break up a section
of a stored procedure that is needed in a number of places. Always for
use in a select.
If the database crashes, gets rolled back, anything, I don't care
about the contents of that
table. Especially -I don't want redo logs for it-. Is there any way I
can accomplish this?

From what I can see so far I should look into: - unrecoverable
- insert /*+APPEND */ into temp_table select... - possibly using a table
variable

Nologging is on by default for a tempory table but you still get some
logging

Am I on the right track?

thanks


The storage for temporary tables is allocated entirely from the temporary
tablespace. Blocks in a temporary tablespace are not proteced by redo so
nologging is on by default as you say. Even more than that, there is no
"current version" and "read consistent" version of the temporary blocks.
Temporary blocks are written from PGA to temporary tablespace in a way
very similar to what /*+ APPEND */ hint does. In other words, that hint is
for normal insert and has no visible effect on inserting into global
temporary tables. To verify that, you can run it with the event 10046,
level 12 and see that there are no visible differences in the trace file.

But there is a bit of redo because of the undo:

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:15826034070548#50549336675394

(Hopefully that link works...)

Kind regards

robert


--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
codefragment at (no spam) googlemail.com...
Posted: Tue Sep 08, 2009 1:32 pm
Guest
I've included an example below, yes I know the sql sucks but I've just
copied a template file to
get something working, no need for a package, etc.

It assumes a table called DeleteMe, e.g.

create table DeleteMe(
someColumn int);

and a table called OneToTen, same structure as the above, which holds
10 values. Just a quick way of building a result set of 1 million
rows.

I truncate DeleteMe, drop the temporary table after a single use.
Again just for expediency, I'm assuming it won;t
affect the result.

What I find is looking in the archive directory I get 130M of files
created for the temporary tables rows and 242M of
files created for the real table rows. So not too much difference.
What I've read suggests that that the redo logs should grow through
the inserts into the temporary table by a much lesser degree than
those into the real table. So what am I doing wrong here (no sarcastic
answers please)





CREATE OR REPLACE PACKAGE MYTEST AS
PROCEDURE MYTEST (
pIgnore IN NUMBER);
END ;

/

CREATE GLOBAL TEMPORARY TABLE TP_MYTEST
(
SOMECOLUMN INT
) ON COMMIT DELETE ROWS;
--) ON COMMIT PRESERVE ROWS;

CREATE OR REPLACE PACKAGE BODY MyTest AS
PROCEDURE MyTest (
pIgnore IN NUMBER) is

BEGIN

-- insert into TP_MYTEST
insert into DeleteMe
select 1 from onetoten t1
join onetoten t2 on 1=1
join onetoten t3 on 1=1
join onetoten t4 on 1=1
join onetoten t5 on 1=1
join onetoten t6 on 1=1;

END MyTest;
END MyTest;
/
 
Eugene Pokopac...
Posted: Tue Sep 08, 2009 2:06 pm
Guest
Because the contents are temporary, they don't generate redo. They
still generate undo, that's true. The undo segment updates cause
'some'
redo to be produced, but nevertheless: the amount of redo an update on
a
temporary table causes should be much less than the amount of redo an
identical 'proper' table would create. That means less log switches,
less
checkpoints, less archives etc. Again, much lower overhead.
 
codefragment at (no spam) googlemail.com...
Posted: Tue Sep 08, 2009 2:44 pm
Guest
Quote:
the amount of redo an update on a temporary table causes should be
much less than the amount of redo an
identical 'proper' table would create.

which isn't what I'm seeing here
 
Randolf Geist...
Posted: Wed Sep 09, 2009 8:30 am
Guest
On Sep 8, 3:32 pm, "codefragm... at (no spam) googlemail.com"
<codefragm... at (no spam) googlemail.com> wrote:
Quote:
I've included an example below, yes I know the sql sucks but I've just
copied a template file to
get something working, no need for a package, etc.

As discussed above, if your main interest is to avoid REDO generation,
you have two options:

- Use the temporary table and add the "/*+ APPEND */" hint to the
insert:

insert /*+ append */ into ...

- Use a conventional table, mark it with NOLOGGING either at create
time or later with ALTER TABLE ... NOLOGGING, and again additionally
use the "/*+ APPEND */" hint when running the insert

Both approaches should minimize your REDO generation.

As already mentioned, you need to be aware of that:

- Enabled indexes on either form of tables will still generate REDO,
UNDO, and REDO for the UNDO

- Direct-path inserts have restrictions. You can check for a
successful direct-path operation by querying the modified object
within the same transaction; you'll get a "ORA-12838: cannot read/
modify an object after modifying it in parallel" if you was a
successful direct-path operation. If you can still access the object
after the insert within the same transaction, it was a conventional
DML operation.

- This also means that you can't access an object modified by direct-
path inserts within the same transaction which needs to be considered
for your process logic. You need to commit to access the inserted the
rows which means a "on commit delete rows" temporary table doesn't
make sense with a direct-path insert operation, since after the commit
the data will be gone.

- Direct-Path inserts always allocate new blocks above the current
High Water Mark (HWM) of the segment and don't reuse any free space in
already allocated blocks. So a repeated "delete + insert /*+ append
*/" operation will let the segment grow every time because the empty
blocks won't get re-used. You would need to truncate instead of delete
to reset the HWM of the segment, if your process logic allows for it
due to the implicit commit performed by truncate.

Regards,
Randolf

Oracle related stuff blog:
http://oracle-randolf.blogspot.com/

SQLTools++ for Oracle (Open source Oracle GUI for Windows):
http://www.sqltools-plusplus.org:7676/
http://sourceforge.net/projects/sqlt-pp/
 
codefragment at (no spam) googlemail.com...
Posted: Wed Sep 09, 2009 12:28 pm
Guest
Quote:
- This also means that you can't access an object modified by direct-
path inserts within the same transaction which needs to be considered
for your process logic. You need to commit to access the inserted the
rows which means a "on commit delete rows" temporary table doesn't
make sense with a direct-path insert operation, since after the commit
the data will be gone.

Thanks for the reply.
I gather you can have Autonomous Transactions within a procedure, so I
could:
- start a transaction,
- load the temporary table up,
- do my selects
- commit the transaction,

then carry on with the rest of the procedure?

Any views on that?
 
 
Page 1 of 2    Goto page 1, 2  Next
All times are GMT
The time now is Sun Mar 21, 2010 3:47 pm