Discussione:
Oracle - Allocazione dello spazio
(troppo vecchio per rispondere)
soulsacrifire
2005-07-06 08:51:22 UTC
Permalink
Salve a tutti esperti di Oracle,
vi illustro il seguente problema:
ho una tabella che ha la seguente struttura:
A123 (
OBJECTID NUMBER (38) NOT NULL,
NUM NUMBER (5) NOT NULL,
TIPONUM VARCHAR2 (2) NOT NULL,
DAL NUMBER (9,3) NOT NULL,
AL NUMBER (9,3) NOT NULL,
LEDAL VARCHAR2 (5) NOT NULL,
LEAL VARCHAR2 (5) NOT NULL,
TIPOLOGIA NUMBER (5) NOT NULL,
COORDXCALCOLATA NUMBER (20,6),
COORDYCALCOLATA NUMBER (20,6),
PERCENTUALE NUMBER (9,2),
IDSTRADE NUMBER (9),
CODPRO NUMBER (5) NOT NULL,
COORDXEFFETTIVA NUMBER (20,6),
COORDYEFFETTIVA NUMBER (20,6),
STRINT_ NUMBER (8),
SDE_STATE_ID NUMBER (38) NOT NULL)

tuttora ha la 0 righe ma alloca ben 27Mega con 3330 blocchi.
Qlche ipotesi su tutto questo spazio allocato?
Un saluto a tutti voi.
matteooooo
2005-07-06 18:33:01 UTC
Permalink
Post by soulsacrifire
Salve a tutti esperti di Oracle,
A123 (
OBJECTID NUMBER (38) NOT NULL,
NUM NUMBER (5) NOT NULL,
TIPONUM VARCHAR2 (2) NOT NULL,
DAL NUMBER (9,3) NOT NULL,
AL NUMBER (9,3) NOT NULL,
LEDAL VARCHAR2 (5) NOT NULL,
LEAL VARCHAR2 (5) NOT NULL,
TIPOLOGIA NUMBER (5) NOT NULL,
COORDXCALCOLATA NUMBER (20,6),
COORDYCALCOLATA NUMBER (20,6),
PERCENTUALE NUMBER (9,2),
IDSTRADE NUMBER (9),
CODPRO NUMBER (5) NOT NULL,
COORDXEFFETTIVA NUMBER (20,6),
COORDYEFFETTIVA NUMBER (20,6),
STRINT_ NUMBER (8),
SDE_STATE_ID NUMBER (38) NOT NULL)
tuttora ha la 0 righe ma alloca ben 27Mega con 3330 blocchi.
Qlche ipotesi su tutto questo spazio allocato?
Un saluto a tutti voi.
creata ex-novo oppure già utilizzata?
se già utilizzata ti conviene troncare la tabella droppando lo storage
se è nuova dipende quanto spazio hai allocato....

Ciao
Matteo
soulsacrifire
2005-07-07 07:36:34 UTC
Permalink
Ciao Matteo,
La tabella è già stata utilizzata.
Essendo parte di una strumento di appoggio per una "replica", posso
ipotizzare che di dati ne abbia visti e poi, una volta terminata la
replica, sia stata "svuotata" del contenuto.
Per lo spazio da deallocare, era già mia intenzione di riallocarlo..
Vabbè procederò con una piccola alter ;)
grazie ancora,
Simone
aaa
2005-07-11 12:38:21 UTC
Permalink
Post by soulsacrifire
La tabella è già stata utilizzata.
Puoi provare a fare un delete di tutto anche se è vuota (cosa stupida ma
chissà) e poi prova a fare un analyze della tabella oppure se hai tempo del
database... a me almeno aggiorna l'interfaccia in java col num di record
effettivi magari a te aggiorna le cifre di spazio allocato :oP

Chissà che funzioni...

Poi mi fai sapere?

Ciao spero di esserti stato utile!
Fabrizio
2005-07-11 18:55:49 UTC
Permalink
Post by aaa
Post by soulsacrifire
La tabella è già stata utilizzata.
Puoi provare a fare un delete di tutto anche se è vuota (cosa stupida ma
chissà) e poi prova a fare un analyze della tabella oppure se hai tempo del
database... a me almeno aggiorna l'interfaccia in java col num di record
effettivi magari a te aggiorna le cifre di spazio allocato :oP
Chissà che funzioni...
Poi mi fai sapere?
Ciao spero di esserti stato utile!
Mi spiace intromettermi cosi' ma una delete non puo' azzerare
l'high-water mark.

Una volta che gli extent sono stati allocati o li riutilizzi oppure usi
una DDL come la truncate (o la clausula "deallocate unused") per
rilasciare lo spazio.

Ciao
--
Fabrizio Magni

***@mycontinent.com

replace mycontinent with europe
soulsacrifire
2005-07-12 15:19:24 UTC
Permalink
Ciao Fabrizio,
ciao aaa,

grazie per i suggerimenti.

Allora, per tutte le tabelle ho fatto l'analyze per ottenere le ultime
info sulle stesse. Di queste una ventina mi dicono che ad es. il calcolo
num_row * avg_row_len è pari a 0 , ma dalla dba_segments ho un pò di
blocchi usati.

Un altro esempio la tabella A128 occupa 19M sulla colonna
DBA_SEGMENTS.BYTES, mentre il calcolo USER_TABLES.AVG_ROW_LEN * NUM_ROWS
= 4M.

Questa tabella non rientra in quelle tabelle che occupano spazio da
deallocare.
Cosa posso verificare per eliminare questa differenza?
In totale lo spazio occupato dalle tabelle per la dba_segments è 570M
contro i 260M della user_tables.

Problemi di deframmentazione?
A presto,
Simone
Fabrizio
2005-07-12 17:48:27 UTC
Permalink
Ciao Simone,
per spiegare a fondo il tuo problema servirebbe un bel po' di teoria e
questo non e' il luogo, quindi semplifichero'.

In generale ogni oggetto oracle e' un segmento (fanno eccezione oggetti
particolari come le tabelle partizionate).
Un segmento e' composto da extent che non sono altro che un insieme di
blocchi contigui la cui grandezza dipende dalle cluasule di storage che
hai specificato all'atto di creazione della tabella o della tablespace
(la grandezza puo' essere variabile o fissa).

I blocchi sono l'unita' minima di allocazione. La grandezza del blocco
oracle e' definita all'atto di creazione del DB (anche se dalla 9i puoi
avere tablespace con blocchi oracle diversi da quelli del DB).

Un blocco oracle solitamente non e' totalmente riempito (le ragioni sono
varie).

A questo punto quanto occupa una tabella?
Post by soulsacrifire
Allora, per tutte le tabelle ho fatto l'analyze per ottenere le ultime
info sulle stesse. Di queste una ventina mi dicono che ad es. il calcolo
num_row * avg_row_len è pari a 0 , ma dalla dba_segments ho un pò di
blocchi usati.
Anche se non contiene nulla un oggetto deve essere un segmento (sempre
tranne i casi particolari) quindi deve avere almeno un extent allocato
(quindi diversi blocchi oracle che dipendono dalle clausule specificate).

Percio' anche le tabelle vuote occupano spazio (ancora di piu' se queste
sono state svuotate con una delete) e num_row * avg_row_len non e'
indicativo per l'occupazione di spazio.
Post by soulsacrifire
Un altro esempio la tabella A128 occupa 19M sulla colonna
DBA_SEGMENTS.BYTES, mentre il calcolo USER_TABLES.AVG_ROW_LEN * NUM_ROWS
= 4M.
I blocchi non sono mai (o quasi) totalmente riempiti percio'
l'occupazione di un oggetto e' superiore ai dati che effettivamente
contiene.
Per di piu' le cancellazioni via delete non deallocano i segmenti, che
rimango riservati per l'oggetto stesso.
Viene richiesto atto esplicito per il reset dell'high water mark (vedi
truncate o alter table).
Post by soulsacrifire
Questa tabella non rientra in quelle tabelle che occupano spazio da
deallocare.
Cosa posso verificare per eliminare questa differenza?
In totale lo spazio occupato dalle tabelle per la dba_segments è 570M
contro i 260M della user_tables.
La dba_segments contiene i dati effettivi che ti servono.

le *_tables, invece, solo statistiche che servono al CBO per calcolare
il miglior piano di esecuzione delle query.
Post by soulsacrifire
Problemi di deframmentazione?
No, quello e' un altro problema (o meglio: altri problemi).

Scusa se ho mancato di chiarezza o sono stato troppo superficiale (la
fretta).

Ciao
--
Fabrizio Magni

***@mycontinent.com

replace mycontinent with europe
soulsacrifire
2005-07-13 12:39:58 UTC
Permalink
Ma nessun problema, anzi hai rinfrescato alcune idee disperse nel tempo..

Ho provveduto con una serie di alter table move tablespace a "resettare"
l'HWM per poi deallocare lo spazio non usato. Così sono riuscito ad
avere una differenza di spazio di soli 68M tra le due stime.

Il fatto è che i dba del cliente mi stressano facendo i conti dello
spazio sul num_rows*avg_row_len e non sulla dba_segments.
So abbastanza bene che una tabella può crescere di spazio per vari
motivi, per mancato studio dello spazio minimo per una insert, al
chained row, etc. . Mi chiedevo se potevo studiare altro per stimare
meglio gli oggetti.

Tuttora tramite una alter table move tablespace ho resettato l'hwm e,
con la dbms_space, ho deallocato lo spazio non usato limitando la
differenza tra avg*row e segments a 68M. Spero che ai sistemisti possa
bastare questa poca differenza di stima...

Grazie ancora,
Simone

Ps. ma in oem non esisteva lo strumento per visualizzare la struttura di
un tablespace? nella 8i si, nella 9i e 10g è sparito?
Fabrizio
2005-07-13 14:08:50 UTC
Permalink
Post by soulsacrifire
Il fatto è che i dba del cliente mi stressano facendo i conti dello
spazio sul num_rows*avg_row_len e non sulla dba_segments.
So abbastanza bene che una tabella può crescere di spazio per vari
motivi, per mancato studio dello spazio minimo per una insert, al
chained row, etc. . Mi chiedevo se potevo studiare altro per stimare
meglio gli oggetti.
Non per fare polemica con situazioni o DBA che non conosco ma calcolare
lo spazio nel DB usando num_rows*avg_row_len non ha senso.

Ogni blocco oracle non e' quasi mai pieno cosi' come vi e' spazio libero
negli extent (che sono le unita' di allocazione che si devono contare!).

Tra l'altro num_rows e avg_row_len sono statistiche che possono essere
stimate e non calcolate al centisimo (oltre ad essere ferme nel tempo).

Ripeto: usare quei parametri per conoscere l'occupazione di spazio e'
follia!!!!

(Consiglia ai DBA la lettura di un manuale).
--
Fabrizio Magni

***@mycontinent.com

replace mycontinent with europe
Fabrizio
2005-07-13 21:06:37 UTC
Permalink
Post by Fabrizio
Post by soulsacrifire
Il fatto è che i dba del cliente mi stressano facendo i conti dello
spazio sul num_rows*avg_row_len e non sulla dba_segments.
So abbastanza bene che una tabella può crescere di spazio per vari
motivi, per mancato studio dello spazio minimo per una insert, al
chained row, etc. . Mi chiedevo se potevo studiare altro per stimare
meglio gli oggetti.
Non per fare polemica con situazioni o DBA che non conosco ma calcolare
lo spazio nel DB usando num_rows*avg_row_len non ha senso.
Ogni blocco oracle non e' quasi mai pieno cosi' come vi e' spazio libero
negli extent (che sono le unita' di allocazione che si devono contare!).
Tra l'altro num_rows e avg_row_len sono statistiche che possono essere
stimate e non calcolate al centisimo (oltre ad essere ferme nel tempo).
Ripeto: usare quei parametri per conoscere l'occupazione di spazio e'
follia!!!!
(Consiglia ai DBA la lettura di un manuale).
Ok, ho ricevuto una mail in cui mi si diceva che non ho provato
l'affermazione cosi' eccomi a ripostare.

Prego di scusare l'uso dell'utente system ma non avevo a disposizione
altro da qui.

Ho creato un tabella pippo:

SQL> select count(*) from pippo;

COUNT(*)
----------
22852

La analizzo e controllo cio' che le statistiche mi dicono:

SQL> exec dbms_stats.gather_table_stats('SYSTEM','PIPPO');

PL/SQL procedure successfully completed.


SQL> select TABLE_NAME,AVG_ROW_LEN,NUM_ROWS from user_tables where
table_name='PIPPO';

TABLE_NAME AVG_ROW_LEN NUM_ROWS
------------------------------ ----------- ----------
PIPPO 63 22852


Nel frattempo ecco cosa la user_segments mi dice dell'allocazione di spazio:

SQL> select BYTES,BLOCKS,EXTENTS from user_segments where
SEGMENT_NAME='PIPPO';

BYTES BLOCKS EXTENTS
---------- ---------- ----------
2097152 256 17


Ora tronco la tabella:

SQL> truncate table pippo;

Table truncated.



SQL> select count(*) from pippo;

COUNT(*)
----------
0


Come si vede non contiene righe.

Ma le mie statistiche mi dicono il contrario:

SQL> select TABLE_NAME,AVG_ROW_LEN,NUM_ROWS from user_tables where
table_name='PIPPO';

TABLE_NAME AVG_ROW_LEN NUM_ROWS
------------------------------ ----------- ----------
PIPPO 63 22852

(Ovvio visto che non sono state ricomputate).

Ma la mia user_segments mi da':

SQL> select BYTES,BLOCKS,EXTENTS from user_segments where
SEGMENT_NAME='PIPPO';

BYTES BLOCKS EXTENTS
---------- ---------- ----------
65536 8 1

Cioe' i reali valori di occupazione.

Come si vede un extent e' allocato.
Ogni oggetto ha sempre almeno un extent. Mai meno (anche se non contiene
nulla).
percio' anche un oggetto vuoto occupa spazio.


Visto che le statistiche non sono sempre calcolate ma a volte solo
stimate usare quei valori per calcolare l'occupazione di spazio ha poco
senso (o nulla del tutto).

Spero di aver convinto qualche scettico...

Buona notte.

PS: la tablespace map c'e' anche nella 9i e nella 10gR2 (anche se in
questa non e' proprio il massimo). Manca invece nella 10gR1.
--
Fabrizio Magni

***@mycontinent.com

replace mycontinent with europe
Enrico "Henryx" Bianchi
2005-07-14 21:16:36 UTC
Permalink
Post by soulsacrifire
Essendo parte di una strumento di appoggio per una "replica", posso
ipotizzare che di dati ne abbia visti e poi, una volta terminata la
replica, sia stata "svuotata" del contenuto.
Leggendo questa frase mi chiedo perché tu voglia riallocare quella
tabella. Se la tabella ti serve, allora tanto vale lasciarla delle
dimensioni attuali (l'unica preoccupazione che avrei è ricrearla con le
apposite clausole di storage, oppure fare un export/import del db, in
maniera da essere sicuro di avere veramente una allocazione contigua).
Se la tabella non ti serve, allora tanto vale troncarla

Henryx
P.S. tieni presente che senza le opportune opzioni di storage, le
tabelle in oracle tendono a frammentarsi (hai capito bene, si
frammentano)
Fabrizio
2005-07-15 08:41:57 UTC
Permalink
Post by Enrico "Henryx" Bianchi
Leggendo questa frase mi chiedo perché tu voglia riallocare quella
tabella. Se la tabella ti serve, allora tanto vale lasciarla delle
dimensioni attuali (l'unica preoccupazione che avrei è ricrearla con le
apposite clausole di storage, oppure fare un export/import del db, in
maniera da essere sicuro di avere veramente una allocazione contigua).
Se la tabella non ti serve, allora tanto vale troncarla
Mi schiero a sfavore della export/import.
Se vuoi riorganizzare una tabella e' molto piu' semplice e veloce una move.
Meno step, meno possibilita' di commettere errori, nessun problema con i
constraint, tempo minore e non devi nemmeno bloccare la tua applicazione
(ricordarsi di eseguire una rebuild degli indici che verranno resi
unusable).
Post by Enrico "Henryx" Bianchi
Henryx
P.S. tieni presente che senza le opportune opzioni di storage, le
tabelle in oracle tendono a frammentarsi (hai capito bene, si
frammentano)
Qui intendevi tablespace fragmentation?

Con l'introduzione delle LMT, il problema non sussiste (o comunque la
sua portata e ridottissima).
O lasci a oracle il compito di decidere la grandezza degli extent (e
quindi tu hai poche possibilita' di pilotare le scelte) o usi un
segmento uniforme quindi non avrai *mai* frammentazione delle tablespace.

Discorso diverso se parli di DMT... ma ormai se non per vecchi sistemi o
bug particolari, queste sono cadute in disuso.

A meno di macroscopici errori la frammentazione delle tablespace e'
ormai un non-problema.

In tutti i casi e' buona pratica specificare le clausule di storage a
livello di tablespace e non di oggetto.

(oppure per tabella frammentata intendevi row chaining e migration?)

ciao
--
Fabrizio Magni

***@mycontinent.com

replace mycontinent with europe
Enrico "Henryx" Bianchi
2005-07-16 11:49:38 UTC
Permalink
Post by Fabrizio
Qui intendevi tablespace fragmentation?
Si
Post by Fabrizio
In tutti i casi e' buona pratica specificare le clausule di storage a
livello di tablespace e non di oggetto.
Punti di vista. Personalmente, preferisco mantenere un controllo totale
dello storage, impostando a tal proposito i parametri di storage dei
singoli oggetti e facendone un rebuild ogni tot giorniin maniera da
mantenere sempre 1 extent (si, sono paranoico, ma dato che il db deve
essere utilizzato per un datawarehouse...). Per quanto riguarda il
discorso del move, sinceramente non sapevo nemmeno dell'esistenza di
tale parametro (molto utile, visto che mi ha permesso di estendere il
rebuild anche alle tabelle)
Post by Fabrizio
(oppure per tabella frammentata intendevi row chaining e migration?)
Sinceramente non capisco cosa intendi. Per tabella frammentata intendo
una tabella da più di un extent non contiguo

Henryx
Fabrizio
2005-07-16 11:58:30 UTC
Permalink
Post by Enrico "Henryx" Bianchi
Post by Fabrizio
Qui intendevi tablespace fragmentation?
Si
Post by Fabrizio
In tutti i casi e' buona pratica specificare le clausule di storage a
livello di tablespace e non di oggetto.
Punti di vista. Personalmente, preferisco mantenere un controllo totale
dello storage, impostando a tal proposito i parametri di storage dei
singoli oggetti e facendone un rebuild ogni tot giorniin maniera da
mantenere sempre 1 extent (si, sono paranoico, ma dato che il db deve
essere utilizzato per un datawarehouse...). Per quanto riguarda il
discorso del move, sinceramente non sapevo nemmeno dell'esistenza di
tale parametro (molto utile, visto che mi ha permesso di estendere il
rebuild anche alle tabelle)
Post by Fabrizio
(oppure per tabella frammentata intendevi row chaining e migration?)
Sinceramente non capisco cosa intendi. Per tabella frammentata intendo
una tabella da più di un extent non contiguo
Henryx
Ciao Enrico,
avevo proprio paura che tu scrivessi una cosa simile.

1 extent per oggetto e' ormai un ito oracle (ti cosiglio la lettura di
Howard J Rogers, Jeremiah Wilton o Jonathan Lewis).

(Prova questo link per farti un'idea generale
http://www.speakeasy.org/~jwilton/oracle/oracle-misconceptions.html).

Avere un oggetto in un sole extent non aumentera' le tue performancema
ti portera' ad avere problemi (come la frammentazione di cui parlavi) e
maggiore lavoro.

Non e' una caso di paranoia ma di bad practice.

Perfino nelle vecchie DMT si era arrivati a sconsigliare il singolo
extent per oggetto.

Mentre per le cluasule di storage lo ribadisco: tranne casi
particolarissimi meglio averle a livello tablespace.
Al massimo creane altre dove hai requisiti particolari.
--
Fabrizio Magni

***@mycontinent.com

replace mycontinent with europe
soulsacrifire
2005-07-18 08:38:42 UTC
Permalink
Vi ringrazio tutti per le informazioni che mi avete fornito.
Grazie ancora per tutto il supporto..

Simone
Enrico "Henryx" Bianchi
2005-07-24 19:44:00 UTC
Permalink
Post by Fabrizio
Avere un oggetto in un sole extent non aumentera' le tue performancema
ti portera' ad avere problemi (come la frammentazione di cui parlavi) e
maggiore lavoro.
Scusa, ma questo mi sembra qualcosa di differente da quello che ho
provato[1]. Avendo la tabella su più extent (clausola STORAGE impostata
con i valori di default) mi sono ritrovato con la tabella frammentata
all'ennesima potenza (era una tabella di auditing in cui venivano fatti
quattro inserimenti per ogni record presente sulla tabella principale) e
dalle prestazioni più che infime

Henryx
[1] a meno che non stiamo utilizzando lo stesso termine per indicare due
operazioni differenti
Fabrizio
2005-07-27 08:09:39 UTC
Permalink
Post by Enrico "Henryx" Bianchi
Post by Fabrizio
Avere un oggetto in un sole extent non aumentera' le tue performancema
ti portera' ad avere problemi (come la frammentazione di cui parlavi) e
maggiore lavoro.
Scusa, ma questo mi sembra qualcosa di differente da quello che ho
provato[1].
Ciao Henryx,
mi spiace scriverlo ma mi sono perso la dimostrazione.
Post by Enrico "Henryx" Bianchi
Avendo la tabella su più extent (clausola STORAGE impostata
con i valori di default) mi sono ritrovato con la tabella frammentata
all'ennesima potenza (era una tabella di auditing in cui venivano fatti
quattro inserimenti per ogni record presente sulla tabella principale) e
dalle prestazioni più che infime
Rotorno a chiederlo: frammentazione di tabella o tablespace?
Visto che hai gia' risposto tablespace (e tabella avrebbe poco senso)
allora definiamo cos'e' la frammentazione di tablespace e quando puo'
avvenire.

Puoi avere rammentazione solo se:
- usi extent di dimensioni diverse all'interno di una singola tablespace,
- ha deallocato spazio da un segmento e questo non puo' essere
riutilizzato perche' troppo piccolo rispetto all richiesta degli extent
da allocare.

Non vuoi avere frammentazione?
Usa una clausula per un valore di extent uniforme e lo spazio sara'
sempre riutilizzabile.
Hai risolto definitivamente i tuoi problemi di frammentazione.

Ora: tu dici che la tua *tabella* era partizionata. Cosa intendi? Che
era su piu' di un extent? magari non contiguo?
Bhe, questo non e' un problema, ne' di performance ne' di utilizzazione
di spazio.

Il voler inserire l'intero segmento in un extent e' una cattiva pratica:
ti fa lavorare moltissimo, non aumenti le tue performance e butti spazio
(aumenti i rischi di frammentazione: proprio cio' che volevi evitare).

L'argomento e' stato cosi' discusso negli anni passati da divenire una
FAQ del mondo oracle.

un segmento = un extent
serve per le performance e' un mito.

Autori e autori si sono battuti per cercare di estirparlo ed e' per
questo che vorrei sfatarlo anche qui.

Henryx: cercando di crearti oggetti da un segmento ti stai dando la
zappa sui piedi, ben due volte!

La domanda: qual'e' il vantaggio e cosa cerchi di ottenere
impacchettando un segmento in un extent?
Post by Enrico "Henryx" Bianchi
Henryx
[1] a meno che non stiamo utilizzando lo stesso termine per indicare due
operazioni differenti
Ho paura che stiamo parlando proprio della stessa cosa.

PS: spero di non aver dato il tono sbagliato alla mail.
Sto solo tentando di combattere un mito e una cattiva pratica. Non e'
qualcosa di personale.
--
Fabrizio Magni

***@mycontinent.com

replace mycontinent with europe
Enrico "Henryx" Bianchi
2005-07-27 16:25:30 UTC
Permalink
Post by Fabrizio
Ciao Henryx,
mi spiace scriverlo ma mi sono perso la dimostrazione.
Non c'è stata nessuna dimostrazione e forse è meglio farla.

In questo momento, sulla mia istanza di Oracle (9.2.0.5), ho creato due
tabelle (tab1 e tab2) in cui, per tab1, ho queste clausole di storage:
STORAGE (
INITIAL 128K
NEXT 128K
MINEXTENTS 1
MAXEXTENTS 4096
PCTINCREASE 0
FREELISTS 1
FREELIST GROUPS 1
BUFFER_POOL DEFAULT
)

Per tab2, invece, le clausole di storage sono queste:
STORAGE (
INITIAL 213M
NEXT 104M
MINEXTENTS 1
MAXEXTENTS 4096
PCTINCREASE 0
FREELISTS 1
FREELIST GROUPS 1
BUFFER_POOL DEFAULT
)

La tablespace su cui risiedono le tabelle (attualmente occupata per il 70%)
è stata creata con impostazioni simili a queste (sostanzialmente, cambia
solo
il nome della tablespace e dei datafile):

CREATE TABLESPACE PIPPO DATAFILE
'C:\ORACLE\ORADATA\TEST\PIPPO.DBF' SIZE 2000M AUTOEXTEND OFF,
'C:\ORACLE\ORADATA\TEST\PIPPO1.DBF' SIZE 16K AUTOEXTEND OFF,
'C:\ORACLE\ORADATA\TEST\PIPPO2.DBF' SIZE 16K AUTOEXTEND OFF,
'C:\ORACLE\ORADATA\TEST\PIPPO3.ORA' SIZE 2000M AUTOEXTEND OFF,
'C:\ORACLE\ORADATA\TEST\PIPPO4.ORA2' SIZE 2000M AUTOEXTEND OFF
MINIMUM EXTENT 64K
NOLOGGING
DEFAULT STORAGE (
INITIAL 128K
NEXT 128K
MINEXTENTS 1
MAXEXTENTS 4096
PCTINCREASE 0
)
ONLINE
PERMANENT
EXTENT MANAGEMENT DICTIONARY
BLOCKSIZE 8K;

Le tabelle sono identiche sia come struttura di colonne, sia come dati
inseriti (2868115 record per 11 colonne). Le tabelle non hanno indici,
chiavi
primarie o constraints.
La colonna EXTENTS di USER_SEGMENTS riporta, per tab1, il valore 1667,
mentre per tab2 è 1.
L'estrazione di un record da SQL*Plus, su tab2, restituisce come tempistica
(set timing on) questo valore:

Elapsed: 00:00:05.06

L'estrazione dello stesso record, su tab1, restituisce questa tempistica:

Elapsed: 00:00:42.06

A questo punto, se traggo delle conclusioni, ne deduco che:
1) con più extents la tabella è frammentata e perde prestazioni;
2) con un extent riesco ad avere risultati accettabili anche senza indici.

Ed è per questo che non riesco a comprendere appieno ciò che cerchi di
dirmi.

Henryx
P.S. l'estrazione delle clausole di storage e dello script di creazione
della
tablespace l'ho eseguita con Toad (personalmente, come clausole di storage,
inserisco solo MINEXTENTS, MAXEXTENTS e PCTINCREASE)
P.S. scusa se non sono più specifico, ma sono informazioni prese nell'ambito
lavorativo

--------------------------------
Inviato via http://arianna.libero.it/usenet/
Fabrizio
2005-07-28 06:23:09 UTC
Permalink
Ciao Henryx,
la prima cosa che vedo e' la condizione della tablespace:

hai creato in una 9i una DMT invece di una LMT.
Questo ti fara' sempre perdere in performance e consiglio la pratica
solo se hai un bug grave (tipo corruzione di dati) che puo' essere
risolto solo con il vecchio modello di allocazione degli spazi.

Ti consiglio pertanto la ricreazione della tablespace.

Continuando: se non hai indici e' improbabile che ti servano le
statistiche sulle tabelle ma e' sempre meglio averle.

Per le vecchie DMT c'e' un overhead sul numero di extent quindi le
clausule di storage dovrebbero essere scelte per permettere un numero di
extent nell'ordine del centinaio.
Ma ancora la differenza di prestazione puo' essere data da ben altro.

L'uso del termine "tabella frammentata" e' improprio. Il numero di
extent non rappresenta frammentazione.
Cio' che puo' fare la differenza e' su tu hai chained rows o migrated rows.

A questo punto una movimentazione dei blocchi attraverso una move
dovrebbe risolverti il problema.

Ti chiedo quindi la prova: passa ad una LMT (ne acquisirai in
performance e tempo di mantenimento) e movimenta i dati sulla due (poi
ricalcola le statistiche).
Prendi quindi i tempi di esecuzione.

Lo stesso test e' stato fatto centinaia di volte per dimostrare come un
unico segmento non incrementi le performance (comunque, anche nelle LMT
puoi avere un degrado superando i 1000 extent).

Fabrizio

PS: Capisco perfettamente che tu non possa pubblicare qualcosa di
riservato. Non preoccuparti.
--
Fabrizio Magni

***@mycontinent.com

replace mycontinent with europe
gg
2005-07-29 06:54:35 UTC
Permalink
Enrico Henryx Bianchi wrote:
[...]
Post by Enrico "Henryx" Bianchi
L'estrazione di un record da SQL*Plus, su tab2, restituisce come tempistica
Elapsed: 00:00:05.06
Elapsed: 00:00:42.06
1) con più extents la tabella è frammentata e perde prestazioni;
2) con un extent riesco ad avere risultati accettabili anche senza indici.
[...]

[interessante thread]

...le tue conclusioni non sono corrette.
In primis, la tua prova non dimostra (1) in quanto TU pensi che quella
sia l'unica differenza tra le due query.
Errato è l'approccio: se devi paragonare due query che insistono su due
segmenti differenti (volendo apprezzare la differenza di tuning del
segmento) ti DEVI assicurare che le query abbiano lo stesso piano di
esecuzione, che gli oggetti siano possibilmente o entrambi in BP o NON
in BP... e sopratutto devi analizzare i tempi di wait per capire dove
sono effettivamente le differenze. Mi viene in mente anche che il piano
di esecuzione anche se uguale può non bastare, per esempio per via
dell'HWM.
La deduzione (2) è una deduzione che potrebbe essere corretta SES vai
esclusivamente in FTS o FFS (ma non ci puoi andare senza idx) su un
segmento.

.g

Continua a leggere su narkive:
Loading...