Skip to Main Content
  • Questions
  • Tunning query - ORA 01652 unable to extend temp segment

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, zdenek.

Asked: May 05, 2004 - 9:51 am UTC

Last updated: November 28, 2009 - 12:53 pm UTC

Version: 8.1.7

Viewed 1000+ times

You Asked

Hi,
I have problem with query, I always get error message " ORA - 01652 unable to extend temp segment..". (I cannot use ALTER TABLESPACE ADD DATAFILE statement to add one or more files to the tablespace indicated.)
I need get this result, but this query return error ORA - 01652.
What is the best solution?
select a.*, b.*
from
(select t1 from table1
uninon all
select t2 from table2) a

(select t3 from table3
uninon all
select t4 from table4) b

where a.t1 = b.t3

Thanks,
Zdenek





and Tom said...

if you do not configure sufficient temp space (and I'm assuming you have a couple of gig of temp for a normal database)

and you are running out for this

the only other options would involve queries that do not need temp but would likely run for hours, if not days, due to their inherit inefficiencies (use of indexes and massive massive nested loops joins)

Sometimes -- you gotta do what you gotta do.

You could try

select * from t1,t3 where ...
UNION ALL
select * from t1,t4 where ...
UNION ALL
select * from t2,t3 where ....
UNION ALL
select * from t2,t4 where ....

as that would only require sufficient temp space for one of the union alls at a time using a nice big bulky efficient hash join or whatnot. consider:


select a.object_name x, b.created y from
(select * from t1 union all select * from t2) a,
(select * from t3 union all select * from t4) b
where a.object_id = b.object_id

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.01 0.00 0 0 0 0
Fetch 1 0.49 0.56 32 850 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.50 0.56 32 850 0 1

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 127 (recursive depth: 1)

Rows Row Source Operation
------- ---------------------------------------------------
1 HASH JOIN (cr=850 r=32 w=0 time=561741 us)
61271 VIEW (cr=846 r=32 w=0 time=319016 us)
61271 UNION-ALL PARTITION (cr=846 r=32 w=0 time=233966 us)
30635 TABLE ACCESS FULL T3 (cr=423 r=32 w=0 time=27538 us)
30636 TABLE ACCESS FULL T4 (cr=423 r=0 w=0 time=26830 us)
1 VIEW (cr=4 r=0 w=0 time=76 us)
1 UNION-ALL PARTITION (cr=4 r=0 w=0 time=72 us)
1 TABLE ACCESS FULL T1 (cr=4 r=0 w=0 time=57 us)
0 TABLE ACCESS FULL T2 (cr=0 r=0 w=0 time=0 us)
********************************************************************************
select t1.object_name, t3.created from t1, t3 where t1.object_id = t3.object_id union all
select t1.object_name, t4.created from t1, t4 where t1.object_id = t4.object_id union all
select t2.object_name, t3.created from t2, t3 where t2.object_id = t3.object_id union all
select t2.object_name, t4.created from t2, t4 where t2.object_id = t4.object_id

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.09 0.14 32 427 0 1
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 3 0.09 0.14 32 427 0 1

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: 127 (recursive depth: 1)

Rows Row Source Operation
------- ---------------------------------------------------
1 UNION-ALL (cr=427 r=32 w=0 time=140682 us)
1 HASH JOIN (cr=427 r=32 w=0 time=140673 us)
30635 TABLE ACCESS FULL T3 (cr=423 r=32 w=0 time=26778 us)
1 TABLE ACCESS FULL T1 (cr=4 r=0 w=0 time=53 us)
0 HASH JOIN (cr=0 r=0 w=0 time=0 us)
0 TABLE ACCESS FULL T4 (cr=0 r=0 w=0 time=0 us)
0 TABLE ACCESS FULL T1 (cr=0 r=0 w=0 time=0 us)
0 HASH JOIN (cr=0 r=0 w=0 time=0 us)
0 TABLE ACCESS FULL T3 (cr=0 r=0 w=0 time=0 us)
0 TABLE ACCESS FULL T2 (cr=0 r=0 w=0 time=0 us)
0 HASH JOIN (cr=0 r=0 w=0 time=0 us)
0 TABLE ACCESS FULL T4 (cr=0 r=0 w=0 time=0 us)
0 TABLE ACCESS FULL T2 (cr=0 r=0 w=0 time=0 us)


the 4 way union all can start getting stuff back way before the 2 way one does in this case -- hence, it needs less temp space (if any) since it is dealing with the stuff in smaller chunks.

However.... the price you'll pay in not having right sized your temp will be:

select t1.object_name, t3.created from t1, t3 where t1.object_id = t3.object_id
union all
select t1.object_name, t4.created from t1, t4 where t1.object_id = t4.object_id
union all
select t2.object_name, t3.created from t2, t3 where t2.object_id = t3.object_id
union all
select t2.object_name, t4.created from t2, t4 where t2.object_id = t4.object_id

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 8170 1.88 1.86 395 11460 0 122534
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 8172 1.88 1.87 395 11460 0 122534

Rows Row Source Operation
------- ---------------------------------------------------
122534 UNION-ALL (cr=11460 r=395 w=0 time=1484556 us)
30633 HASH JOIN (cr=2865 r=201 w=0 time=308438 us)
30635 TABLE ACCESS FULL T3 (cr=423 r=32 w=0 time=26417 us)
30633 TABLE ACCESS FULL T1 (cr=2442 r=169 w=0 time=52605 us)
30633 HASH JOIN (cr=2873 r=162 w=0 time=265903 us)
30636 TABLE ACCESS FULL T4 (cr=423 r=0 w=0 time=25965 us)
30633 TABLE ACCESS FULL T1 (cr=2450 r=162 w=0 time=50026 us)
30634 HASH JOIN (cr=2869 r=32 w=0 time=267758 us)
30635 TABLE ACCESS FULL T3 (cr=423 r=32 w=0 time=26504 us)
30634 TABLE ACCESS FULL T2 (cr=2446 r=0 w=0 time=51702 us)
30634 HASH JOIN (cr=2853 r=0 w=0 time=262829 us)
30636 TABLE ACCESS FULL T4 (cr=423 r=0 w=0 time=26263 us)
30634 TABLE ACCESS FULL T2 (cr=2430 r=0 w=0 time=46918 us)
********************************************************************************
select a.object_name x, b.created y
from
(select * from t1 union all select * from t2) a,
(select * from t3 union all select * from t4) b
where a.object_id = b.object_id

call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 8170 1.64 1.62 197 9778 0 122534
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 8172 1.64 1.62 197 9778 0 122534

Rows Row Source Operation
------- ---------------------------------------------------
122534 HASH JOIN (cr=9778 r=197 w=0 time=1231281 us)
61271 VIEW (cr=846 r=32 w=0 time=313097 us)
61271 UNION-ALL PARTITION (cr=846 r=32 w=0 time=228575 us)
30635 TABLE ACCESS FULL OBJ#(37576) (cr=423 r=32 w=0 time=29814 us)
30636 TABLE ACCESS FULL OBJ#(37577) (cr=423 r=0 w=0 time=27248 us)
61267 VIEW (cr=8932 r=165 w=0 time=435410 us)
61267 UNION-ALL PARTITION (cr=8932 r=165 w=0 time=337034 us)
30633 TABLE ACCESS FULL OBJ#(37574) (cr=4458 r=165 w=0 time=67484 us)
30634 TABLE ACCESS FULL OBJ#(37575) (cr=4474 r=0 w=0 time=64505 us)

extra work to get the last row back!





Rating

  (4 ratings)

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

Comments

decode function

A reader, November 23, 2009 - 7:39 am UTC

Hi Tom,
I have a materialized view with the query a),
I try to change this query with the query b)

the only difference is the elimination of the union all
ad the use of the decode function.

With the query b) I have
the error
ORA-01652: unable to extend temp segment by 8192 in tablespace TEMP


the question is:
does the decode function impact on TEMP consuming?

thanks and best regards
Mauro

b)

SELECT
output.NU_ANNOMM AS NU_ANNOMM,
.......
output.CO_TP_REND AS CO_TP_REND,
decode(output.CO_VOCE,'ST_ATRNDIS',output.CO_PIVA, 'CT_CONS_B' ,output.CO_PIVA,null) AS CO_PIVA,
SUM (output.VA_IMPORTO) AS VA_IMPORTO,
SUM (output.VA_IMPORTO_ALLOC) AS VA_IMPORTO_ALLOC
FROM
TBRC_DATI_COMPENSI output
WHERE
output.FL_COMPENSO = 'S'
GROUP BY
output.NU_ANNOMM,
.......
output.CO_TP_REND,
decode(output.CO_VOCE,'ST_ATRNDIS',output.CO_PIVA, 'CT_CONS_B' ,output.CO_PIVA,null)



a)

SELECT
output.NU_ANNOMM AS NU_ANNOMM,
........
output.CO_TP_REND AS CO_TP_REND,
output.CO_PIVA AS CO_PIVA,
SUM (output.VA_IMPORTO) AS VA_IMPORTO,
SUM (output.VA_IMPORTO_ALLOC) AS VA_IMPORTO_ALLOC
FROM
VMRC_COMPENSO_ABI output
WHERE
output.FL_COMPENSO = 'S'
and co_voce in ('ST_ATRNDIS', 'CT_CONS_B')
GROUP BY
output.NU_ANNOMM,
....
output.CO_TP_REND,
output.CO_PIVA,
union all
SELECT
output.NU_ANNOMM AS NU_ANNOMM,
output.CO_TP_REND AS CO_TP_REND,
null AS CO_PIVA,
SUM (output.VA_IMPORTO) AS VA_IMPORTO,
SUM (output.VA_IMPORTO_ALLOC) AS VA_IMPORTO_ALLOC
FROM
VMRC_COMPENSO_ABI output
WHERE
output.FL_COMPENSO = 'S'
and not(co_voce in ('ST_ATRNDIS', 'CT_CONS_B'))
GROUP BY
output.NU_ANNOMM,
output.CO_TP_REND
Tom Kyte
November 23, 2009 - 4:38 pm UTC

you are comparing a union all query against tables VMRC_COMPENSO_ABI and VMRC_COMPENSO_ABI to a query against a third table TBRC_DATI_COMPENSI ??????


Well, the union all query is done sequentially - one after the other really - so the temp needs for it would be whatever the first bit needs AND THEN whatever the second bit needs

where as the second query does everything in one pass.


I doubt it has anything to do with decode

It has everything to do with the size of TBRC_DATI_COMPENSI versus the other two, it'll be larger or having many more distinct values for the group by list

follow up

Mauro, November 24, 2009 - 3:44 am UTC

ops! excuse me, I wrong coping an other snapshot query,
the source table is the same (TBRC_DATI_COMPENSI),
the 2 correct query are:



b)

SELECT
output.NU_ANNOMM AS NU_ANNOMM,
output.CO_VOCE AS CO_VOCE,
output.CO_ABI AS CO_ABI,
output.CO_GRUPPO AS CO_GRUPPO,
output.DT_MESE AS DT_MESE,
output.DT_ANNO AS DT_ANNO,
output.CO_CAB AS CO_CAB,
output.CO_PRODOTTO AS CO_PRODOTTO,
output.CO_PERSONALIZ AS CO_PERSONALIZ,
output.CO_SCAGLIONE AS CO_SCAGLIONE,
output.CO_CIRCUITO AS CO_CIRCUITO,
output.CO_OPE AS CO_OPE,
output.CO_TECNO AS CO_TECNO,
output.FL_COMPENSO AS FL_COMPENSO,
output.CO_PRES_CARTA AS CO_PRES_CARTA,
output.CO_TP_CER AS CO_TP_CER,
output.CO_TP_RISK AS CO_TP_RISK,
output.CO_TP_REND AS CO_TP_REND,
decode(output.CO_VOCE,'ST_ATRNDIS',output.CO_PIVA, 'CT_CONS_B' ,output.CO_PIVA,null) AS CO_PIVA,
output.CO_PROP_POS AS CO_PROP_POS,
decode(FL_CHIP_MOV, '2', 'S', '4', 'S', '5', 'S', 'N') AS FL_CHIP_MOV,
SUM (output.VA_DRIVER) AS VA_DRIVER,
output.VA_PARAM AS VA_PARAM,
SUM (output.VA_IMPORTO) AS VA_IMPORTO,
SUM (output.VA_IMPORTO_ALLOC) AS VA_IMPORTO_ALLOC
FROM
TBRC_DATI_COMPENSI output
WHERE
output.FL_COMPENSO = 'S'
GROUP BY
output.NU_ANNOMM,
output.CO_VOCE,
output.CO_ABI,
output.CO_GRUPPO,
output.DT_MESE,
output.DT_ANNO,
output.CO_CAB,
output.CO_PRODOTTO,
output.CO_PERSONALIZ,
output.CO_SCAGLIONE,
output.CO_CIRCUITO,
output.CO_OPE,
output.CO_TECNO,
output.FL_COMPENSO,
output.CO_PRES_CARTA,
output.CO_TP_CER,
output.CO_TP_RISK,
output.CO_TP_REND,
decode(output.CO_VOCE,'ST_ATRNDIS',output.CO_PIVA, 'CT_CONS_B' ,output.CO_PIVA,null),
output.CO_PROP_POS,
decode(FL_CHIP_MOV, '2', 'S', '4', 'S', '5', 'S', 'N'),
output.VA_PARAM;



a)

SELECT output.nu_annomm AS nu_annomm, output.co_voce AS co_voce,
output.co_abi AS co_abi, output.co_gruppo AS co_gruppo,
output.dt_mese AS dt_mese, output.dt_anno AS dt_anno,
output.co_cab AS co_cab, output.co_prodotto AS co_prodotto,
output.co_personaliz AS co_personaliz,
output.co_scaglione AS co_scaglione,
output.co_circuito AS co_circuito, output.co_ope AS co_ope,
output.co_tecno AS co_tecno, output.fl_compenso AS fl_compenso,
output.co_pres_carta AS co_pres_carta, output.co_tp_cer AS co_tp_cer,
output.co_tp_risk AS co_tp_risk, output.co_tp_rend AS co_tp_rend,
output.co_piva AS co_piva,
output.co_prop_pos AS co_prop_pos,
DECODE (fl_chip_mov,
'2', 'S',
'4', 'S',
'5', 'S',
'N'
) AS fl_chip_mov,
SUM (output.va_driver) AS va_driver, output.va_param AS va_param,
SUM (output.va_importo) AS va_importo,
SUM (output.va_importo_alloc) AS va_importo_alloc
FROM tbrc_dati_compensi output
WHERE output.fl_compenso = 'S' AND co_voce IN ('ST_ATRNDIS', 'CT_CONS_B')
GROUP BY output.nu_annomm,
output.co_voce,
output.co_abi,
output.co_gruppo,
output.dt_mese,
output.dt_anno,
output.co_cab,
output.co_prodotto,
output.co_personaliz,
output.co_scaglione,
output.co_circuito,
output.co_ope,
output.co_tecno,
output.fl_compenso,
output.co_pres_carta,
output.co_tp_cer,
output.co_tp_risk,
output.co_tp_rend,
output.co_piva,
output.co_prop_pos,
DECODE (fl_chip_mov, '2', 'S', '4', 'S', '5', 'S', 'N'),
output.va_param
UNION ALL
SELECT output.nu_annomm AS nu_annomm, output.co_voce AS co_voce,
output.co_abi AS co_abi, output.co_gruppo AS co_gruppo,
output.dt_mese AS dt_mese, output.dt_anno AS dt_anno,
output.co_cab AS co_cab, output.co_prodotto AS co_prodotto,
output.co_personaliz AS co_personaliz,
output.co_scaglione AS co_scaglione,
output.co_circuito AS co_circuito, output.co_ope AS co_ope,
output.co_tecno AS co_tecno, output.fl_compenso AS fl_compenso,
output.co_pres_carta AS co_pres_carta, output.co_tp_cer AS co_tp_cer,
output.co_tp_risk AS co_tp_risk, output.co_tp_rend AS co_tp_rend,
NULL AS co_piva,
output.co_prop_pos AS co_prop_pos,
DECODE (fl_chip_mov,
'2', 'S',
'4', 'S',
'5', 'S',
'N'
) AS fl_chip_mov,
SUM (output.va_driver) AS va_driver, output.va_param AS va_param,
SUM (output.va_importo) AS va_importo,
SUM (output.va_importo_alloc) AS va_importo_alloc
FROM tbrc_dati_compensi output
WHERE output.fl_compenso = 'S' AND co_voce NOT IN ('ST_ATRNDIS', 'CT_CONS_B')
GROUP BY output.nu_annomm,
output.co_voce,
output.co_abi,
output.co_gruppo,
output.dt_mese,
output.dt_anno,
output.co_cab,
output.co_prodotto,
output.co_personaliz,
output.co_scaglione,
output.co_circuito,
output.co_ope,
output.co_tecno,
output.fl_compenso,
output.co_pres_carta,
output.co_tp_cer,
output.co_tp_risk,
output.co_tp_rend,
output.co_prop_pos,
DECODE (fl_chip_mov, '2', 'S', '4', 'S', '5', 'S', 'N'),
output.va_param


the single query with the decode seems more temp consuming.

thanks
Mauro
Tom Kyte
November 24, 2009 - 11:23 am UTC

I gave you enough for you to be able to guess at what might be happening.


if you build two small sets one at a time... versus one set all at once.


question to you, if you size your temp correctly (make it larger) which one is more efficient?

I'll guess that one that does the single pass.

followup

Mauro, November 25, 2009 - 5:00 am UTC

Yes, the single pass query is more efficient and probably more fast,
the problem is that
a developer wrote a materialized view refresh complete over
a 2.000.000.000 rows table!!!
the temp is now 50Gb!!

I don't want enlarge the temp...
I want to rewrite all

Many many thanks and regards
Mauro
Tom Kyte
November 25, 2009 - 2:54 pm UTC

using temp is the most efficient way to do this

If you avoid temp, say for example do it to use a nested loop with indexing - you will use less temp but infinitely more cpu, wall clock time, probably IO (definitely logical IO, probably physical IO too).

Your choice - the old saying is "penny wise, pound foolish".

50gb - once upon a few years ago, that was a large number. In 2009, it is but a drop in the bucket.

different results?

jian huang zheng, November 26, 2009 - 4:51 am UTC

Hi tom
from your previous answer, the price of not properly sized temp will be different result?

Fetch 8170 1.88 1.86 395 11460 0 122534

I am not sure why different result is returned? (one row vs 122534)?

Thanks,
Tom Kyte
November 28, 2009 - 12:53 pm UTC

No, I was showing what would happen if you had big data in there, you would start using temp.

In the first examples, I only fetched once - in the second bit, I kept on going to fetch them all.


I was showing how the plans "stop" being evaluated if you don't fetch everything. The union all bits are not done until you hit them


looks like the last bit of the original answer got chopped off though, it should finish with:

However.... the price you'll pay in not having right sized your temp will be:

select t1.object_name, t3.created from t1, t3 where t1.object_id = t3.object_id
union all
select t1.object_name, t4.created from t1, t4 where t1.object_id = t4.object_id
union all
select t2.object_name, t3.created from t2, t3 where t2.object_id = t3.object_id
union all
select t2.object_name, t4.created from t2, t4 where t2.object_id = t4.object_id



call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0 0
Execute      1      0.00       0.00          0          0          0 0
Fetch     8170      1.88       1.86        395      11460          0      12253 4
------- ------  -------- ---------- ---------- ---------- ----------  --------- -
total     8172      1.88       1.87        395      11460          0      12253 4


Rows     Row Source Operation
-------  ---------------------------------------------------
 122534  UNION-ALL  (cr=11460 r=395 w=0 time=1484556 us)
  30633   HASH JOIN  (cr=2865 r=201 w=0 time=308438 us)
  30635    TABLE ACCESS FULL T3 (cr=423 r=32 w=0 time=26417 us)
  30633    TABLE ACCESS FULL T1 (cr=2442 r=169 w=0 time=52605 us)
  30633   HASH JOIN  (cr=2873 r=162 w=0 time=265903 us)
  30636    TABLE ACCESS FULL T4 (cr=423 r=0 w=0 time=25965 us)
  30633    TABLE ACCESS FULL T1 (cr=2450 r=162 w=0 time=50026 us)
  30634   HASH JOIN  (cr=2869 r=32 w=0 time=267758 us)
  30635    TABLE ACCESS FULL T3 (cr=423 r=32 w=0 time=26504 us)
  30634    TABLE ACCESS FULL T2 (cr=2446 r=0 w=0 time=51702 us)
  30634   HASH JOIN  (cr=2853 r=0 w=0 time=262829 us)
  30636    TABLE ACCESS FULL T4 (cr=423 r=0 w=0 time=26263 us)
  30634    TABLE ACCESS FULL T2 (cr=2430 r=0 w=0 time=46918 us)
*******************************************************************************
*
select a.object_name x, b.created y
from
(select * from t1 union all select * from t2) a,
(select * from t3 union all select * from t4) b
where a.object_id = b.object_id


call     count       cpu    elapsed       disk      query    current        row s
------- ------  -------- ---------- ---------- ---------- ----------  --------- -
Parse        1      0.00       0.00          0          0          0 0
Execute      1      0.00       0.00          0          0          0 0
Fetch     8170      1.64       1.62        197       9778          0      12253 4
------- ------  -------- ---------- ---------- ---------- ----------  --------- -
total     8172      1.64       1.62        197       9778          0      12253 4^M


Rows     Row Source Operation
-------  ---------------------------------------------------
 122534  HASH JOIN  (cr=9778 r=197 w=0 time=1231281 us)
  61271   VIEW  (cr=846 r=32 w=0 time=313097 us)
  61271    UNION-ALL PARTITION (cr=846 r=32 w=0 time=228575 us)
  30635     TABLE ACCESS FULL OBJ#(37576) (cr=423 r=32 w=0 time=29814 us)
  30636     TABLE ACCESS FULL OBJ#(37577) (cr=423 r=0 w=0 time=27248 us)
  61267   VIEW  (cr=8932 r=165 w=0 time=435410 us)
  61267    UNION-ALL PARTITION (cr=8932 r=165 w=0 time=337034 us)
  30633     TABLE ACCESS FULL OBJ#(37574) (cr=4458 r=165 w=0 time=67484 us)
  30634     TABLE ACCESS FULL OBJ#(37575) (cr=4474 r=0 w=0 time=64505 us)

 extra work to get the last row back!



comparing what happens to each when you fetch all of the way through - I was comparing "get me the first row with as little work as possible" vs "get me all of them"

More to Explore

Performance

Get all the information about database performance in the Database Performance guide.