dbTalk Databases Forums  

Multi table insert; does it do a single pass over the source?

comp.databases.ibm-db2 comp.databases.ibm-db2


Discuss Multi table insert; does it do a single pass over the source? in the comp.databases.ibm-db2 forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Doug B
 
Posts: n/a

Default Multi table insert; does it do a single pass over the source? - 08-11-2010 , 06:54 PM






I found this example by Serge of a multi table insert in a thread from
2008:

WITH source(c1, c2, c3) AS (VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9)),
ins1(d) AS (SELECT 1
FROM NEW TABLE(INSERT INTO T1(c1)
SELECT c1 FROM source
WHERE c3 < 5)),
ins2(d) AS (SELECT 1
FROM NEW TABLE(INSERT INTO T2(c2)
SELECT c2 FROM source
WHERE c3 BETWEEN 5 AND 8)),
ins3(d) AS (SELECT 1
FROM NEW TABLE(INSERT INTO T3(c3)
SELECT c3 FROM source
WHERE c3 > 8))
VALUES 1;

I've been able to successfully use this form on my DB2 9.1
installation, but I can't tell from the plan whether DB2 is scanning
the source multiple times, once per insert target, or just once. How
could I prove one or the other to myself? For a VALUES source it
doesn't matter much, but if the source is a complex, multi-table join
it would.

Thanks!

Reply With Quote
  #2  
Old   
Serge Rielau
 
Posts: n/a

Default Re: Multi table insert; does it do a single pass over the source? - 08-12-2010 , 10:55 AM






On 8/11/2010 7:54 PM, Doug B wrote:
Quote:
I found this example by Serge of a multi table insert in a thread from
2008:

WITH source(c1, c2, c3) AS (VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9)),
ins1(d) AS (SELECT 1
FROM NEW TABLE(INSERT INTO T1(c1)
SELECT c1 FROM source
WHERE c3< 5)),
ins2(d) AS (SELECT 1
FROM NEW TABLE(INSERT INTO T2(c2)
SELECT c2 FROM source
WHERE c3 BETWEEN 5 AND 8)),
ins3(d) AS (SELECT 1
FROM NEW TABLE(INSERT INTO T3(c3)
SELECT c3 FROM source
WHERE c3> 8))
VALUES 1;

I've been able to successfully use this form on my DB2 9.1
installation, but I can't tell from the plan whether DB2 is scanning
the source multiple times, once per insert target, or just once. How
could I prove one or the other to myself? For a VALUES source it
doesn't matter much, but if the source is a complex, multi-table join
it would.
The optimizer plan will clearly show the common table expression i.e.
source.
And yes it will do multiple passes.
If you want to do it in one pass you have two choices.
1. Use a dynamic compound
BEGIN ATOMIC
FOR myrow AS SELECT * FROM T DO
INSERT INTO T1 SELECT * FROM (VALUES (myrow.c1, ....))
AS S1(c1, ..) WHERE c3 < 5;
INSERT INTO T2 SELECT * FROM (VALUES (myrow.c1, ....))
AS S1(c1, ..) WHERE c3 BETWEEN 5 AND 8;
...
END FOR;
END

2. Build a union all view and insert into that.
CREATE VIEW v AS
SELECT * FROM T1 WHERE c3 < 5
UNION ALL SELECT .....

INSERT INTO v SELECT ....

It's been a long time since I have done insert through union all but it
should work.

The dynamic compound should be the fastest though.



--
Serge Rielau
SQL Architect DB2 for LUW
IBM Toronto Lab

Reply With Quote
  #3  
Old   
Doug B
 
Posts: n/a

Default Re: Multi table insert; does it do a single pass over the source? - 08-12-2010 , 11:20 AM



On Aug 12, 8:55*am, Serge Rielau <srie... (AT) ca (DOT) ibm.com> wrote:
Quote:
On 8/11/2010 7:54 PM, Doug B wrote:



I found this example by Serge of a multi table insert in a thread from
2008:

WITH source(c1, c2, c3) AS (VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9)),
* * ins1(d) AS (SELECT 1
* * * * * * * * * FROM NEW TABLE(INSERT INTO T1(c1)
* * * * * * * * * * * * * * * * *SELECT c1 FROM source
* * * * * * * * * * * * * * * * * WHERE c3< *5)),
* * ins2(d) AS (SELECT 1
* * * * * * * * * FROM NEW TABLE(INSERT INTO T2(c2)
* * * * * * * * * * * * * * * * *SELECT c2 FROM source
* * * * * * * * * * * * * * * * * WHERE c3 BETWEEN 5 AND 8)),
* * ins3(d) AS (SELECT 1
* * * * * * * * * FROM NEW TABLE(INSERT INTO T3(c3)
* * * * * * * * * * * * * * * * *SELECT c3 FROM source
* * * * * * * * * * * * * * * * * WHERE c3> *8))
VALUES 1;

I've been able to successfully use this form on my DB2 9.1
installation, but I can't tell from the plan whether DB2 is scanning
the source multiple times, once per insert target, or just once. *How
could I prove one or the other to myself? *For a VALUES source it
doesn't matter much, but if the source is a complex, multi-table join
it would.

The optimizer plan will clearly show the common table expression i.e.
source.
And yes it will do multiple passes.
If you want to do it in one pass you have two choices.
1. Use a dynamic compound
BEGIN ATOMIC
* *FOR myrow AS SELECT * FROM T DO
* * *INSERT INTO T1 SELECT * FROM (VALUES (myrow.c1, ....))
* * * * *AS S1(c1, ..) WHERE c3 < 5;
* * *INSERT INTO T2 SELECT * FROM (VALUES (myrow.c1, ....))
* * * * *AS S1(c1, ..) WHERE c3 BETWEEN 5 AND 8;
* * *...
* * END FOR;
END

2. Build a union all view and insert into that.
* CREATE VIEW v AS
* * SELECT * FROM T1 WHERE c3 < 5
* * UNION ALL SELECT .....

* INSERT INTO v SELECT ....

It's been a long time since I have done insert through union all but it
should work.

The dynamic compound should be the fastest though.

--
Serge Rielau
SQL Architect DB2 for LUW
IBM Toronto Lab- Hide quoted text -

- Show quoted text -
Thanks for the reply, Serge. I had thought I'd proven to myself that
only one pass was occurring by doing a test using a SEQUENCE object in
the source/common table expression like so:

WITH
source AS(
SELECT NEXTVAL FOR my_schema.my_seq id
FROM sysibm.sysdummy1),
ins1(d) AS (
SELECT 1
FROM NEW TABLE(INSERT
INTO my_schema.table_001
SELECT *
FROM source
WHERE id between 0 and 999999999)
),
ins2(d) AS (
SELECT 1
FROM NEW TABLE(INSERT
INTO my_schema.table_002
SELECT *
FROM source
WHERE id between 0 and 999999999)
),
ins3(d) AS (
SELECT 1
FROM NEW TABLE(INSERT
INTO my_schema.table_003
SELECT *
FROM source
WHERE id between 0 and 999999999)
)
VALUES 1;

The 3 "target" tables each contained the same id value from the
sequence, not three consecutive ones, so my assumption was that only a
single pass against the source had happened.

Reply With Quote
  #4  
Old   
Serge Rielau
 
Posts: n/a

Default Re: Multi table insert; does it do a single pass over the source? - 08-12-2010 , 09:39 PM



On 8/12/2010 12:20 PM, Doug B wrote:
Quote:
On Aug 12, 8:55 am, Serge Rielau<srie... (AT) ca (DOT) ibm.com> wrote:
On 8/11/2010 7:54 PM, Doug B wrote:



I found this example by Serge of a multi table insert in a thread from
2008:

WITH source(c1, c2, c3) AS (VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9)),
ins1(d) AS (SELECT 1
FROM NEW TABLE(INSERT INTO T1(c1)
SELECT c1 FROM source
WHERE c3< 5)),
ins2(d) AS (SELECT 1
FROM NEW TABLE(INSERT INTO T2(c2)
SELECT c2 FROM source
WHERE c3 BETWEEN 5 AND 8)),
ins3(d) AS (SELECT 1
FROM NEW TABLE(INSERT INTO T3(c3)
SELECT c3 FROM source
WHERE c3> 8))
VALUES 1;

I've been able to successfully use this form on my DB2 9.1
installation, but I can't tell from the plan whether DB2 is scanning
the source multiple times, once per insert target, or just once. How
could I prove one or the other to myself? For a VALUES source it
doesn't matter much, but if the source is a complex, multi-table join
it would.

The optimizer plan will clearly show the common table expression i.e.
source.
And yes it will do multiple passes.
If you want to do it in one pass you have two choices.
1. Use a dynamic compound
BEGIN ATOMIC
FOR myrow AS SELECT * FROM T DO
INSERT INTO T1 SELECT * FROM (VALUES (myrow.c1, ....))
AS S1(c1, ..) WHERE c3< 5;
INSERT INTO T2 SELECT * FROM (VALUES (myrow.c1, ....))
AS S1(c1, ..) WHERE c3 BETWEEN 5 AND 8;
...
END FOR;
END

2. Build a union all view and insert into that.
CREATE VIEW v AS
SELECT * FROM T1 WHERE c3< 5
UNION ALL SELECT .....

INSERT INTO v SELECT ....

It's been a long time since I have done insert through union all but it
should work.

The dynamic compound should be the fastest though.

--
Serge Rielau
SQL Architect DB2 for LUW
IBM Toronto Lab- Hide quoted text -

- Show quoted text -

Thanks for the reply, Serge. I had thought I'd proven to myself that
only one pass was occurring by doing a test using a SEQUENCE object in
the source/common table expression like so:

WITH
source AS(
SELECT NEXTVAL FOR my_schema.my_seq id
FROM sysibm.sysdummy1),
ins1(d) AS (
SELECT 1
FROM NEW TABLE(INSERT
INTO my_schema.table_001
SELECT *
FROM source
WHERE id between 0 and 999999999)
),
ins2(d) AS (
SELECT 1
FROM NEW TABLE(INSERT
INTO my_schema.table_002
SELECT *
FROM source
WHERE id between 0 and 999999999)
),
ins3(d) AS (
SELECT 1
FROM NEW TABLE(INSERT
INTO my_schema.table_003
SELECT *
FROM source
WHERE id between 0 and 999999999)
)
VALUES 1;

The 3 "target" tables each contained the same id value from the
sequence, not three consecutive ones, so my assumption was that only a
single pass against the source had happened.
Well.. true, but the the result is stored in a temp table which is then
scanned three times.



--
Serge Rielau
SQL Architect DB2 for LUW
IBM Toronto Lab

Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.