About Oracle Table defragmentation

Source: Internet
Author: User

Database in the daily use of the process, continuous insert,delete,update operation, resulting in the table and index fragmentation is inevitable, fragmentation is more, SQL execution efficiency naturally poor, the reason is very simple, high watermark (HWL) Many data blocks are no data, But the full table scan to scan to the high watermark data block, that is to say Oracle to do a lot of useless! As a result, Oracle provides shrink space defragmentation capabilities. For indexes, you can take rebuild online defragmentation, in general, the objects that are frequently DML operations are regularly maintained by DBAs, while keeping in mind that statistics are updated in a timely manner!

One: Prepare test data, use HR user, create T1 table, insert approximately 30W of data, and create normal index according to object_id, table occupies 34M of storage space, index occupies about 6M storage space

  1. SQL> Conn/as sysdba
  2. is connected.
  3. SQL> select Default_tablespace from dba_users where username=' HR ';
  4. Default_tablespace
  5. ------------------------------------------------------------
  6. USERS
  7. SQL> Conn hr/hr
  8. is connected.
  9. SQL> INSERT INTO T1 select * from T1;
  10. 74812 rows have been created.
  11. SQL> INSERT INTO T1 select * from T1;
  12. 149624 rows have been created.
  13. SQL> commit;
  14. Submit complete.
  15. SQL> CREATE index idx_t1_id on T1 (object_id);
  16. The index has been created.
  17. SQL> Exec dbms_stats.gather_table_stats (' HR ', ' T1 ',cascade=>true);
  18. The PL/SQL process has completed successfully.
  19. SQL> select COUNT (1) from T1;
  20. COUNT (1)
  21. ----------
  22. 299248
  23. SQL> select sum (bytes)/1024/1024 from dba_segments where segment_name=' T1 ';
  24. SUM (BYTES)/1024/1024
  25. --------------------
  26. 34.0625
  27. SQL> select sum (bytes)/1024/1024 from dba_segments where segment_name=' idx_t1_id ';
  28. SUM (BYTES)/1024/1024
  29. --------------------
  30. 6

Second: Estimate how much space is available under the high watermark, the lower the better, the higher the table usage is to the high watermark, the less work done by the full table scan!

Dbms_stats package cannot get empty_blocks statistics, so you need to collect statistics with analyze command again

  1. SQL> SELECT blocks, Empty_blocks, num_rows from user_tables WHERE table_name =' T1 ';
  2. BLOCKS Empty_blocks Num_rows
  3. ---------- ------------ ----------
  4. 4302 0 299248
  5. SQL> Analyze table T1 compute statistics;
  6. Table has been analyzed.
  7. SQL> SELECT blocks, Empty_blocks, num_rows from user_tables WHERE table_name =' T1 ';
  8. BLOCKS Empty_blocks Num_rows
  9. ---------- ------------ ----------
  10. 4302 50 299248
  11. SQL> Col table_name for A20
  12. SQL> SELECT table_name,
  13. 2 (BLOCKS * 8192/1024/1024)-
  14. 3 (Num_rows * avg_row_len/1024/1024) "Data lower than HWM in MB"
  15. 4 from User_tables
  16. 5 WHERE table_name = ' T1 ';
  17. TABLE_NAME Data lower than HWM in MB
  18. -------------------- -------------------------
  19. T1 5.07086182

Three: View execution plan, full table scan probably consumes CPU 1175

  1. SQL> Explain plan for select * from T1;
  2. has been explained.
  3. SQL> select * from table (dbms_xplan.display);
  4. Plan_table_output
  5. --------------------------------------------------------------------------------
  6. Plan Hash value:3617692013
  7. --------------------------------------------------------------------------
  8. | Id | Operation | Name | Rows | Bytes | Cost (%CPU) | Time |
  9. --------------------------------------------------------------------------
  10. | 0 |      SELECT STATEMENT |   |    299k|  28m| 1175 (1) | 00:00:15 |
  11. |  1 | TABLE ACCESS full|   T1 |    299k|  28m| 1175 (1) | 00:00:15 |
  12. --------------------------------------------------------------------------

Four: Delete Most of the data, collect statistics, full table scan still need to consume CPU 1168

  1. SQL> Delete from t1 where object_id>100;
  2. 298852 rows have been deleted.
  3. SQL> commit;
  4. Submit complete.
  5. SQL> select COUNT (*) from T1;
  6. COUNT (*)
  7. ----------
  8. 396
  9. SQL> Exec dbms_stats.gather_table_stats (' HR ', ' T1 ',cascade=>true);
  10. The PL/SQL process has completed successfully.
  11. SQL> Analyze table T1 compute statistics;
  12. Table has been analyzed.
  13. SQL> SELECT blocks, Empty_blocks, num_rows from user_tables WHERE table_name =' T1 ';
  14. BLOCKS Empty_blocks Num_rows
  15. ---------- ------------ ----------
  16. 4302 50 396
  17. SQL> Explain plan for select * from T1;
  18. has been explained.
  19. SQL> select * from table (dbms_xplan.display);
  20. Plan_table_output
  21. ------------------------------------------------------------------------------
  22. Plan Hash value:3617692013
  23. --------------------------------------------------------------------------
  24. | Id | Operation | Name | Rows | Bytes | Cost (%CPU) | Time |
  25. --------------------------------------------------------------------------
  26. | 0 |      SELECT STATEMENT |   | 396 |  29700 | 1168 (1) | 00:00:15 |
  27. |  1 | TABLE ACCESS full|   T1 | 396 |  29700 | 1168 (1) | 00:00:15 |
  28. --------------------------------------------------------------------------

Five: Estimate how much space is not available under the high watermark, but it also needs to be hard-working data for full-table scanning

  1. SQL> SELECT table_name,
  2. 2 (BLOCKS * 8192/1024/1024)-
  3. 3 (Num_rows * avg_row_len/1024/1024) "Data lower than HWM in MB"
  4. 4 from User_tables
  5. 5 WHERE table_name = ' T1 ';
  6. TABLE_NAME Data lower than HWM in MB
  7. -------------------- -------------------------
  8. T1 33.5791626

VI: Defragment the table and collect statistics again

  1. SQL> ALTER TABLE T1 enable row movement;
  2. The table has changed.
  3. SQL> ALTER TABLE T1 shrink space cascade;
  4. The table has changed.
  5. SQL> select sum (bytes)/1024/1024 from dba_segments where segment_name=' T1 ';
  6. SUM (BYTES)/1024/1024
  7. --------------------
  8. .125
  9. SQL> select sum (bytes)/1024/1024 from dba_segments where segment_name= ' idx_t1_id
  10. ‘;
  11. SUM (BYTES)/1024/1024
  12. --------------------
  13. .0625
  14. SQL> SELECT table_name,
  15. 2 (BLOCKS * 8192/1024/1024)-
  16. 3 (Num_rows * avg_row_len/1024/1024) "Data lower than HWM in MB"
  17. 4 from User_tables
  18. 5 WHERE table_name = ' T1 ';
  19. TABLE_NAME Data lower than HWM in MB
  20. -------------------- -------------------------
  21. T1 33.5791626
  22. SQL> Exec dbms_stats.gather_table_stats (' HR ', ' T1 ',cascade=>true);
  23. The PL/SQL process has completed successfully.
  24. At this time, only 0.1M of useless work, the execution plan, full table scan also only need to consume CPU 3
  25. SQL> SELECT table_name,
  26. 2 (BLOCKS * 8192/1024/1024)-
  27. 3 (Num_rows * avg_row_len/1024/1024) "Data lower than HWM in MB"
  28. 4 from User_tables
  29. 5 WHERE table_name = ' T1 ';
  30. TABLE_NAME Data lower than HWM in MB
  31. -------------------- -------------------------
  32. T1.010738373
  33. SQL> select * from table (dbms_xplan.display);
  34. Plan_table_output
  35. --------------------------------------------------------------------------------
  36. Plan Hash value:3617692013
  37. --------------------------------------------------------------------------
  38. | Id | Operation | Name | Rows | Bytes | Cost (%CPU) | Time |
  39. --------------------------------------------------------------------------
  40. | 0 |      SELECT STATEMENT |   | 396 |     29700 | 3 (0) | 00:00:01 |
  41. |  1 | TABLE ACCESS full|   T1 | 396 |     29700 | 3 (0) | 00:00:01 |
  42. --------------------------------------------------------------------------
  43. A total of only 5 blocks, there are 50 empty blocks, obviously empty_blocks information expires
  44. SQL> select blocks,empty_blocks,num_rows from User_tables where table_name=' T1 ';
  45. BLOCKS Empty_blocks Num_rows
  46. ---------- ------------ ----------
  47. 5 50 396
  48. SQL> Analyze table T1 compute statistics;
  49. Table has been analyzed.
  50. SQL> select blocks,empty_blocks,num_rows from User_tables where table_name=' T1 ';
  51. BLOCKS Empty_blocks Num_rows
  52. ---------- ------------ ----------
  53. 5 3 396

Reference: http://surachartopun.com/2011/08/determine-hwm-and-reduce-it-by-shrink.html

For information on how to determine which tables need to be defragmented, you can use the scripts in the attachments to query them, please refer to: http://www.toadworld.com/KNOWLEDGE/KnowledgeXpertforOracle/tabid/648/ Topicid/otnn18/default.aspx

About Oracle Table defragmentation

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.