Overview
Most Oracle databases use locally managed tablespaces (LMT) today - dictionary managed tablespaces (DMT) are now obsolet. The reasons to use LMTs are the following:
Object fragmentation you would easily get in a DMT cannot happen in a LMT.
The number of extents in an object is not relevant. You need not be concerned with objects that have many extents.
Recursive SQL overhead is virtually entirely gone.
You do not need to try figure out what the optimal INITIAL, NEXT, PCTINCREASE, MAXEXTENTS are. They are no more relevant - if you use them, they are usually disastrous.
For most applications LMTs with system managed extent sizes are fine.
So, remove the STORAGE clause from your CREATE statements - at least the INITAL, NEXT, MAXEXTENTS, MINEXTENTS and PCTINCREASE clauses. But do you exactly know how many FREELISTS to set on your tables and indexes? Do you know the right PCTFREE value set on a segment? If you you answer is no, then Automatic Segment Space Management might be a point to look at. In this article we review FREELISTS with and without ASSM.
Freelists and Freelists Groups
A FREELIST is where Oracle keeps tracks of blocks under the high-water mark for an object. Each will have at least one FREELIST associated with it. As blocks are used, they will be placed or taken off the FREELIST as needed. It is important to note that only blocks under the high-water mark of an object will be found on the FREELIST. The blocks that remain above the high-water mark will be used only when the FREELISTS are empty. In this fashion, Oracle postpones increasing the high-water mark for an object until it must.
An object may have more than one FREELIST. If you anticipate heavy insert or update activity on an object by many concurrent users, configuring more than one FREELIST can make a major positive impact on performance (at the cost of possible additional storage). Individual sessions will be assigned to different FREELISTS, and when they need space, they will not contend with each other.
The cost for the multiple FREELISTS may be additional storage, because a given session will use only one FREELIST for a segment for its entire session. If an object has many FREELISTS and each FREELIST has some blocks on it, a single session doing a large insert operation will ignore all but one of the FREELISTS. When it exhausts the blocks on the FREELIST it is using, it will advance the high-water mark for the table and not use the other free blocks.
Example (Oracle 10.1.0.3)
Parts of this example was published by Tom Kyte. In order to see the differences between a segment with, and without, multiple FREELISTS in a highly concurrent environment, let's set up a test. We start by creating a table test. We'll have five sessions inserting into this table concurrently. We will set up the table with a fixed-width column of 255 bytes. The first test is done with manual segment space management, then the same test once more with auto segment space management.
ASSM Manual with 1 Freelist
sqlplus system/<password>
Create a tablespace which is manual segment space managed:
create tablespace assm_manual
datafile '/u01/oracle/db/AKI1/tab/AKI1_assm_manual.dbf'
size 500M segment space management manual;
Then a table with 1 Freelist within the tablespace:
drop table test;
create table test (
x date,
y char(255) default 'x'
)
storage (freelists 1)
tablespace assm_manual;
Now create a procedure to insert rows into table test for a five minute period. We use DBMS_JOB to run 5 concurrent do_insert procedures, so make sure that JOB_QUEUE_PROCESSES is set to at least 5 in the INIT.ORA file. To measure the I/O performance we use STATSPACK.
create or replace procedure do_insert
as
l_stop date default sysdate+5/24/60;
l_date date default sysdate;
begin
while (l_date < l_stop)
loop
insert into test (x)
values (sysdate)
returning x into l_date;
commit;
end loop;
end;
/
exec perfstat.statspack.snap;
declare
l_job number;
begin
for i in 1 .. 5
loop
dbms_job.submit( l_job, 'do_insert;' );
end loop;
commit;
end;
/
Check that 5 oracle processes are running using the utility top.
$ top
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
14728 oracle 19 0 23152 21m 20m R 18.6 4.3 0:06.39 oracle
14722 oracle 16 0 23104 21m 20m R 18.2 4.3 0:06.51 oracle
14724 oracle 16 0 23060 21m 20m R 18.2 4.3 0:06.44 oracle
14720 oracle 18 0 26152 24m 23m R 17.6 5.0 0:06.58 oracle
14726 oracle 19 0 23088 21m 20m R 16.6 4.3 0:06.39 oracle
Wait until all jobs has been finished using the following statement. If you get no more rows as a result, the jobs has been completed.
select substr(job,1,4) "job",
substr(schema_user,1,10) "user",
substr(to_char(last_date,'dd.mm.yyyy hh24:mi'),1,16) "last date",
substr(to_char(next_date,'dd.mm.yyyy hh24:mi'),1,16) "next date",
substr(broken,1,2) "b",
substr(failures,1,6) "failed",
substr(what,1,32) "command"
from DBA_jobs;
job user last date next date b failed command
---- ---------- ---------------- ---------------- - ------ ----------
41 SCOTT 17.02.2005 13:28 N do_insert;
42 SCOTT 17.02.2005 13:28 N do_insert;
43 SCOTT 17.02.2005 13:28 N do_insert;
44 SCOTT 17.02.2005 13:28 N do_insert;
45 SCOTT 17.02.2005 13:28 N do_insert;
When finished, perform a STATSPACK snapshot:
exec perfstat.statspack.snap
Create the STATSPACK Report:
sqlplus perfstat/perfstat
SQL> @?/rdbms/admin/spreport.sql
Load Profile
~~~~~~~~~~~~ Per Second Per Transaction
--------------- ---------------
Executes: 1,082.17 2.01
Transactions: 537.17
Top 5 Timed Events
~~~~~~~~~~~~~~~~~~ % Total
Event Waits Time (s) Call Time
-------------------------------------------- ------------ ----------- ---------
buffer busy waits 20,307 404 28.33
log file parallel write 40,086 281 19.73
CPU time 275 19.31
job scheduler coordinator slave wait 12 192 13.46
latch: In memory undo latch 8,478 149 10.47
ASSM Manual with 5 Freelists
Now, do exactly the same test, but with 5 FREELISTS.
drop table test;
create table test (
x date,
y char(255) default 'x'
)
storage (freelists 5)
tablespace assm_manual;
exec perfstat.statspack.snap
declare
l_job number;
begin
for i in 1 .. 5
loop
dbms_job.submit( l_job, 'do_insert;' );
end loop;
commit;
end;
/
exec perfstat.statspack.snap
sqlplus perfstat/perfstat
SQL> @?/rdbms/admin/spreport.sql
Load Profile
~~~~~~~~~~~~ Per Second Per Transaction
--------------- ---------------
Executes: 1,351.61 2.02
Transactions: 670.30
Top 5 Timed Events
~~~~~~~~~~~~~~~~~~ % Total
Event Waits Time (s) Call Time
-------------------------------------------- ------------ ----------- ---------
CPU time 270 25.10
log file parallel write 34,750 246 22.85
job scheduler coordinator slave wait 12 192 17.82
buffer busy waits 3,248 83 7.72
latch: In memory undo latch 3,415 68 6.28
As you can see, we increased the transactions-per-second rate from 537 to 670 and reduced the buffer busy wait events from 20,307 to 3,248. The total time waited went from 404 seconds to 270 seconds - fairly a big change.
ASSM Auto with 1 Freelist
Next, repeat the test with auto segment space management - first again with 1 FREELIST. Create a tablespace which is auto segment space managed:
create tablespace assm_auto
datafile '/u01/oracle/db/AKI1/tab/AKI1_assm_auto.dbf'
size 500M segment space management auto;
drop table test;
create table test (
x date,
y char(255) default 'x'
)
storage (freelists 1)
tablespace assm_auto;
create or replace procedure do_insert
as
l_stop date default sysdate+5/24/60;
l_date date default sysdate;
begin
while (l_date < l_stop)
loop
insert into test (x)
values (sysdate)
returning x into l_date;
commit;
end loop;
end;
/
exec perfstat.statspack.snap;
declare
l_job number;
begin
for i in 1 .. 5
loop
dbms_job.submit( l_job, 'do_insert;' );
end loop;
commit;
end;
/
$ top
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
14994 oracle 15 0 30580 29m 27m R 18.2 5.8 0:39.86 oracle
14996 oracle 15 0 33704 30m 24m R 17.9 6.0 0:40.67 oracle
14998 oracle 15 0 33480 29m 24m R 17.9 5.9 0:40.89 oracle
15000 oracle 15 0 33628 30m 24m R 17.9 6.0 0:40.78 oracle
15002 oracle 14 0 27104 25m 24m R 17.9 5.1 0:39.81 oracle
select substr(job,1,4) "job",
substr(schema_user,1,10) "user",
substr(to_char(last_date,'dd.mm.yyyy hh24:mi'),1,16) "last date",
substr(to_char(next_date,'dd.mm.yyyy hh24:mi'),1,16) "next date",
substr(broken,1,2) "b",
substr(failures,1,6) "failed",
substr(what,1,32) "command"
from dba_jobs;
job user last date next date b failed command
---- ---------- ---------------- ---------------- - ------ ------------
61 SCOTT 17.02.2005 14:11 N do_insert;
62 SCOTT 17.02.2005 14:11 N do_insert;
63 SCOTT 17.02.2005 14:11 N do_insert;
64 SCOTT 17.02.2005 14:11 N do_insert;
65 SCOTT 17.02.2005 14:11 N do_insert;
Wait until jobs has been completed ....
exec perfstat.statspack.snap;
sqlplus perfstat/perfstat
SQL> @?/rdbms/admin/spreport.sql
Load Profile
~~~~~~~~~~~~ Per Second Per Transaction
--------------- ---------------
Executes: 1,295.10 2.00
Transactions: 646.65
Top 5 Timed Events
~~~~~~~~~~~~~~~~~~ % Total
Event Waits Time (s) Call Time
-------------------------------------------- ------------ ----------- ---------
CPU time 272 26.35
log file parallel write 31,920 225 21.71
job scheduler coordinator slave wait 12 192 18.57
buffer busy waits 5,669 94 9.10
LGWR wait for redo copy 57,001 57 5.54
ASSM Auto with 5 Freelist
Finally, do the same test, but with 5 FREELISTS.
drop table test;
create table test (
x date,
y char(255) default 'x'
)
storage (freelists 5)
tablespace assm_auto;
exec perfstat.statspack.snap;
declare
l_job number;
begin
for i in 1 .. 5
loop
dbms_job.submit( l_job, 'do_insert;' );
end loop;
commit;
end;
/
Wait until Jobs has been completed ....
exec perfstat.statspack.snap;
sqlplus perfstat/perfstat
SQL> @?/rdbms/admin/spreport.sql
Load Profile
~~~~~~~~~~~~ Per Second Per Transaction
--------------- ---------------
Executes: 1,224.09 2.00
Transactions: 610.75
Top 5 Timed Events
~~~~~~~~~~~~~~~~~~ % Total
Event Waits Time (s) Call Time
-------------------------------------------- ------------ ----------- ---------
CPU time 270 26.06
log file parallel write 31,806 215 20.75
job scheduler coordinator slave wait 12 192 18.55
buffer busy waits 5,925 111 10.69
LGWR wait for redo copy 64,372 64 6.23
As you can see, there is no difference between 1 and 5 FREELISTS, if we use automatic space management. However the result is not as good as with 5 FREELISTS and manual space management.
|
|