• Aucun résultat trouvé

2-17. Reclaiming Unused Index Space

Dans le document Oracle Database 11g (Page 80-84)

Problem

You have an index consuming space in a segment, but without actually using that space. For example, you’re running the following query to display the Segment Advisor’s advice:

SELECT

'Task Name : ' || f.task_name || CHR(10) ||

'Start Run Time : ' || TO_CHAR(execution_start, 'dd-mon-yy hh24:mi') || chr (10) ||

'Segment Name : ' || o.attr2 || CHR(10) ||

'Segment Type : ' || o.type || CHR(10) ||

'Partition Name : ' || o.attr3 || CHR(10) ||

'Message : ' || f.message || CHR(10) ||

'---' Advice FROM dba_advisor_findings f

,dba_advisor_objects o ,dba_advisor_executions e WHERE o.task_id = f.task_id AND o.object_id = f.object_id AND f.task_id = e.task_id

AND e. execution_start > sysdate - 1 AND e.advisor_name = 'Segment Advisor' ORDER BY f.task_name;

The following output is displayed:

ADVICE

--- Task Name : F_REGS Advice

Start Run Time : 19-feb-11 09:32 Segment Name : F_REGS_IDX1 Segment Type : INDEX Partition Name :

Message : Perform shrink, estimated savings is 84392870 bytes.

More Info : Allocated Space:166723584: Used Space:82330714: Reclaimable S pace :84392870:

--- You want to shrink the index to free up the unused space.

Solution

There are a couple of effective methods for freeing up unused space associated with an index:

• Rebuilding the index

• Shrinking the index

Before you perform either of these operations, first check USER_SEGMENTS to verify that the amount of space used corresponds with the Segment Advisor’s advice. In this example, the segment name is F_REGS_IDX1:

SQL> select bytes from user_segments where segment_name = 'F_REGS_IDX1';

BYTES --- 166723584

This example uses the ALTER INDEX...REBUILD statement to re-organize and compact the space used by an index:

SQL> alter index f_regs_idx1 rebuild;

CHAPTER 2 ■ CHOOSING AND OPTIMIZING INDEXES

Alternatively, use the ALTER INDEX...SHRINK SPACE statement to free up unused space in an index—

for example:

SQL> alter index f_regs_idx1 shrink space;

Index altered.

Now query USER_SEGMENTS again to verify that the space has been de-allocated. Here is the output for this example:

BYTES --- 524288

The space consumed by the index has considerably decreased.

How It Works

Usually rebuilding an index is the fastest and most effective way to reclaim unused space consumed by an index. Therefore this is the approach we recommend for reclaiming unused index space. Freeing up space is desirable because it ensures that you use only the amount of space required by an object. It also has the performance benefit that Oracle has fewer blocks to manage and sort through when performing read operations.

Besides freeing up space, you may want to consider rebuilding an index for these additional reasons:

• The index has become corrupt.

• You want to modify storage characteristics (such as changing the tablespace).

• An index that was previously marked as unusable now needs to be rebuilt to make it usable again.

Keep in mind that Oracle attempts to acquire a lock on the table and rebuild the index online. If there are any active transactions that haven’t committed, then Oracle won’t be able to obtain a lock, and the following error will be thrown:

ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired

In this scenario, you can either wait until the there is little activity in the database or try setting the DDL_LOCK_TIMEOUT parameter:

SQL> alter session set ddl_lock_timeout=15;

The DDL_LOCK_TIMEOUT initialization parameter is available in Oracle Database 11g or higher. It instructs Oracle to repeatedly attempt to obtain a lock for the specified amount of time.

If no tablespace is specified, Oracle rebuilds the index in the tablespace in which the index currently exists. Specify a tablespace if you want the index rebuilt in a different tablespace:

SQL> alter index inv_idx1 rebuild tablespace inv_index;

■ Tip

If you’re working with a large index, you may want to consider using features such as

NOLOGGING

and/or

PARALLEL

(see Recipe 2-16 for details).

If you use the ALTER INDEX...SHRINK SPACE operation to free up unused index space, keep in mind that this feature requires that the target object must be created within a tablespace with automatic segment space management enabled. If you attempt to shrink a table or index that has been created in a tablespace using manual segment space management, you’ll receive this error:

ORA-10635: Invalid segment or tablespace type

As we’ve noted elsewhere in this chapter, we recommend that you use the ASSM feature whenever possible. This allows you to take advantage of all the Oracle segment management features.

The ALTER INDEX...SHRINK SPACE statement has a few nuances to be aware of. For example, you can instruct Oracle to attempt only to merge the contents of index blocks (and not free up space) via the COMPACT clause:

SQL> alter index f_regs_idx1 shrink space compact;

The prior operation is equivalent to the ALTER INDEX...COALESCE statement. Here’s an example of using COALESCE:

SQL> alter index f_regs_idx1 coalesce;

If you want to maximize the space compacted, either rebuild the index or use the SHRINK SPACE clause as shown in the “Solution” section of this recipe. It’s somewhat counterintuitive that the COMPACT space doesn’t actually initiate a greater degree of realized free space. The COMPACT clause instructs Oracle to only merge index blocks where possible and not to maximize the amount of space being freed up.

C H A P T E R 3

Dans le document Oracle Database 11g (Page 80-84)