Skip to Main Content
  • Questions
  • Data types - performance considerations - PCTUSed Doubts - Reg

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question.

Asked: May 22, 2001 - 10:39 am UTC

Last updated: August 10, 2004 - 4:24 pm UTC

Version: 8.1.7.0.0

Viewed 1000+ times

You Asked

Hi Tom

1. Assuming that the maximum column length is 100 in a
database then defining the column data types as char is beneficial or varchar2
from the performance point of view.

Pl explain why?

Is reading the data from the block is convenient in case of
char when compared to varchar2?

2. Taking in performance considerations. Whether it is better to define a data_type as number or number(10) assuming that validations are done not to exceed the digits more than 10 at the front end. if so, why?

3. Is there any disadvantage of having the primary key data type as varchar2(10)
instead of number(10) assuming that the column contains only numeric values,
from the performance point of view?

4. why is the default value of pctused is set to 40 and pctfree to 20?

I thought that the ideal combination should be either 40+60 or 20+80?

I thought the ideal combination should be in such a way
that sum of pctused+pctfree should be equal to 100?
Is this correct? So that the space is utilised maximum? Is there going to be any process
overhead by such a combination? If so How?

If we have delete intense database and we have pctfree 20 and pctused 40.
Then the data is scattered across many blocks. Thereby when u issue
a query the data is to be collected from more block leading process overhead.
Is this statement true?

In such a scenario pctfree 20 and pctused 80 would be more appropriate.
Is this statement true?


Regards





and Tom said...

1) a CHAR is simply a a VARCHAR2 that is stored blank padded. A char is stored with a leading byte field -- just like a varchar2. It is in fact a varchar2 that is always the maximum length (or null).

If all of the data in the table would eventually consume 100 bytes (eg: i insert 5 bytes, update it to 10, update it to 20, .... update it to near 100) it would be more efficient to use a char(100) as it preallocated the space and rows will not migrate over time due to updates. If the rows are truly varying length (normal case) a varchar2 is appropriate.

2) you should ALWAYS put the edit in the database anyway. even if the client always does the edit. This is because client applications lie to the database -- have bugs or are rewritten. The edit belongs in the database NO MATTER WHAT.

3) a number(10) would consume less space then a varchar2(10).


1 create table t as
2 select cast( rownum+9999999 as number(10) ) x, cast( rownum+9999999 as varchar2(10) ) y
3 from all_objects
4* where rownum < 100
ops$tkyte@ORA8I.WORLD> /

Table created.

ops$tkyte@ORA8I.WORLD> select min(vsize(x)), max(vsize(x)), min(vsize(y)), max(vsize(y)),
2 avg(vsize(x)), avg(vsize(y))
3 from t;

MIN(VSZE(X)) MAX(VSZE(X)) MIN(VSZE(Y)) MAX(VSZE(Y)) AVG(VSIZE(X)) AVG(VSIZE(Y))
------------ ------------ ------------ ------------ ------------- -------------
2 5 8 8 4.96969697 8

it would take less time to compare (join), less storage in an index and so on to use a number.

there would be a disadvantage to using a varchar2 over a number if the data is truly numeric

4)

it is 40 and 10:

1* select pct_used, pct_free from user_tables where table_name = 'T'
ops$tkyte@ORA8I.WORLD> /

PCT_USED PCT_FREE
---------- ----------
40 10

the sum cannot exceed 100 -- the best value is not a sum of 100. why is it 40/10? They are just reasonable, general purpose numbers. save 10% for updates -- when we have 10% free space -- stop inserting. when the block is 60% free space (40% used) start thinking about using it for inserts again.

The are set somewhat independent of eachother. The default, 10 pct free, simply says "save 10% of the block for updates. we guess that data will grow no more then 10% over time on each block". If I have an 8k block size -- about 800 bytes will be reserved (not available for an INSERT) for udpates. once we hit the pct free mark -- the block is taken OFF of the freelist.

Later we update a row or delete a row on the block. We discover the block is 61% FREE (less then 40% used). That is the signal to put the block back onto the freelist.


In general:

o High PCTFREE, Low PCTUSED – For when you insert lots of data that will be updated and the updates will increase the size of the rows frequently. This reserves a lot of space on the block after inserts (high PCTFREE) and makes it so that the block must almost be empty before getting back onto the free list (low PCTUSED).

o Low PCTFREE, High PCTUSED – If you tend to only ever INSERT or DELETE from the table or if you do update, the update tends to shrink the row in size.


So, you say "we have a delete intensive database" -- that would be a low pctfree and a high pctused, you want the space to be reused as soon as possible.


maybe 10/90 would be better.




Rating

  (5 ratings)

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

Comments

KP, May 23, 2001 - 1:38 am UTC

As usal yr reply is excellent. But u missed
answer to one of my question that is
Whether it is better to define a
data_type as number or number(10)?



String data type

A reader, June 24, 2003 - 6:39 pm UTC

Hi Tom,

I found the following data type in a program:

varx string(1000);

Can you tell me what kind of data type this is and when it is appropiate to use it?

I cannot find any information about this data type in the Oracle documentation.

Thanks for any help with this.




Tom Kyte
June 25, 2003 - 11:42 am UTC

it is in standard.sql as a subtype:

create or replace
package STANDARD AUTHID CURRENT_USER is -- careful on this line; SED edit occurs!

type BOOLEAN is (FALSE, TRUE);

type DATE is DATE_BASE;

type NUMBER is NUMBER_BASE;
subtype FLOAT is NUMBER; -- NUMBER(126)
subtype REAL is FLOAT; -- FLOAT(63)
subtype "DOUBLE PRECISION" is FLOAT;

.....

subtype VARCHAR is VARCHAR2;
subtype STRING is VARCHAR2;






pctused

reader, February 24, 2004 - 6:04 pm UTC

If I set PCTUSED = 0, then the blocks are never reused for future inserts? Is this true? Thanks.

Tom Kyte
February 25, 2004 - 7:45 am UTC

no, not at all.

the block will be used for inserts up until it hits it's pctfree setting. then it would have to effectively empty out before being used for inserts again.

so, upto pctfree -- block is used for subsequent inserts. empty the block and it'll be used for subsequent inserts.

Hi

A reader, August 10, 2004 - 3:33 pm UTC

I am seeing the value of pctused is null for all the tables in my database. I tried to alter the table by setting the value of pctused to 90. Even then it is showing the value as null.
I am checking the value of pctused by quering the user_tables.

Do you know why?

thanks,

Tom Kyte
August 10, 2004 - 4:04 pm UTC

you are using ASSM (automatic segment space management) where by pctused is "not meaningful anymore" perhaps.

Hi

A reader, August 10, 2004 - 4:08 pm UTC

Thanks. I checked the tablespace definition in fact it was set to AUTO.

Do you think setting it to AUTO is good in huge data warehouse environment over setting it to MANUAL?



Tom Kyte
August 10, 2004 - 4:24 pm UTC

in a DW, probably manual -- ASSM was designed for OLTP environments where lots of concurrency (removed the need to set freelists and such). It uses space in order to make things more concurrent.

In a DW, you typically want to pack the data, don't have a high degree of concurrency.

Than again in a DW, you wouldn't be looking at PCTUSED, since you dont really UPDATE :)