數據庫表索引碎片和sql性能分析

 

  1. 查詢碎片

SELECT table_name,

         ROUND ( (blocks * 8), 2) "高水位空間 k",

         ROUND ( (num_rows * avg_row_len / 1024), 2) "真實使用空間 k",

         ROUND ( (blocks * 10 / 100) * 8, 2) "預留空間(pctfree) k",

         ROUND (

            (  blocks * 8

             - (num_rows * avg_row_len / 1024)

             - blocks * 8 * 10 / 100),

            2)

            "浪費空間 k"

    FROM user_tables

   WHERE temporary = 'N'

   and table_name in ('MAIN_TABLE1',

                                  'MAIN_TABLE2',

                                  'MAIN_TABLE3'

                                   ...)

ORDER BY 5 DESC;

說明:如果有碎片浪費空間最好都清理一下。建議清理碎片程度計算範圍

1-(真實使用空間/高水位空間)>8%

 

2、主表開啓行遷移

begin

  for idx in (SELECT 'alter table ' || table_name || ' enable row movement;' row_cur

                FROM user_tables

               WHERE 

table_name in ('MAIN_TABLE1',

                        'MAIN_TABLE2',

                        'MAIN_TABLE3'

                                   ...)

ORDER BY 5 DESC;

) loop

    begin

      execute immediate (idx.row_cur);

    EXCEPTION

      WHEN OTHERS THEN

        dbms_output.put_line(idx.row_cur);

    END;

  end loop;

end;

說明:這是批量執行開啓錶行遷移。在執行行遷移時,將無法進行DML操作。

 

3、收縮表空間

begin

  for idx in (SELECT 'alter table ' || table_name || ' shrink space ;' row_cur

                FROM user_tables

               WHERE 

table_name in ('MAIN_TABLE1',

                         'MAIN_TABLE2',

                         'MAIN_TABLE3'

                                   ...)

ORDER BY 5 DESC;

) loop

    begin

      execute immediate (idx.row_cur);

    EXCEPTION

      WHEN OTHERS THEN

        dbms_output.put_line(idx.row_cur);

    END;

  end loop;

end;

說明:這是批量進行表空間收縮。對於大表收縮時間話費可能比較長,中間切勿中斷。

 

4、收縮索引空間

begin

  for idx in (SELECT 'alter index' || index_name || ' shrink space ;' row_cur

                FROM user_indexes

               WHERE

table_name in ('MAIN_TABLE1',

                         'MAIN_TABLE2',

                         'MAIN_TABLE3'

                                   ...)

ORDER BY 5 DESC;

) loop

    begin

      execute immediate (idx.row_cur);

    EXCEPTION

      WHEN OTHERS THEN

        dbms_output.put_line(idx.row_cur);

    END;

  end loop;

end;

說明:這是批量進行索引空間收縮對於大表索引收縮時間話費可能比較長,中間切勿中斷。

 

 

5、主表關閉行遷移

begin

  for idx in (SELECT 'alter table ' || table_name || ' disable row movemnt;' row_cur

                FROM user_tables

               WHERE 

table_name in ('MAIN_TABLE1',

                         'MAIN_TABLE2',

                         'MAIN_TABLE3'

                                   ...)

ORDER BY 5 DESC;

) loop

    begin

      execute immediate (idx.row_cur);

    EXCEPTION

      WHEN OTHERS THEN

        dbms_output.put_line(idx.row_cur);

    END;

  end loop;

end;

說明:關閉行遷移以後,纔可以進行DML操作。切記打開以後,記得關閉行遷移。

 

6、重建表索引

begin

  for idx in (SELECT 'alter index' || index_name || ' rebuild online;' row_cur

                FROM user_indexes

               WHERE 

table_name in ('MAIN_TABLE1',

                         'MAIN_TABLE2',

                         'MAIN_TABLE3'

                                   ...)

ORDER BY 5 DESC;

) loop

    begin

      execute immediate (idx.row_cur);

    EXCEPTION

      WHEN OTHERS THEN

        dbms_output.put_line(idx.row_cur);

    END;

  end loop;

end;

說明:經過表和索引收縮以後,進行重建索引。使索引正常排列。

 

7、收集主表信息

begin dbms_stats.gather_table_stats(user,'MAIN_TABLE1',cascade=>true);end;

begin dbms_stats.gather_table_stats(user,'MAIN_TABLE2',cascade=>true);end;

begin dbms_stats.gather_table_stats(user,'MAIN_TABLE3',cascade=>true);end;

說明:這是收集主表統計信息,當索引數據準確後,需統計信息收集,使得表統計信息準確,Oracle優化器基於成本開銷才能選擇最優的執行路徑,才能使得SQL語句執行最優執行計劃,SQL性能得以提高。

 

8、SQL語句性能分析

 

1)、數據準備

Drop table test2;

 create table test2 (id number,crt_time date);

 

 begin

   for i in 1 .. 1000000 loop

     insert into test2 (id, crt_time) values (i, sysdate);

   end loop;

 end;

 

2)、性能測試--執行計劃

--沒加索引;

 --查詢

select * from test2 where id between 123 and 77789 ;   

--執行計劃

 如何查看一條SQL的執行計劃?

選中查詢語句,然後按F5(菜單:工具——>解釋計劃)

 

--增加索引

Create  unique index idx_test2_id on test2(id);

--查詢

select * from test2 where id between 123 and 77789 ;  

--執行計劃

 如何查看一條SQL的執行計劃?

選中查詢語句,然後按F5(菜單:工具——>解釋計劃)

 

根據耗費對比,加了索引後的SQL性能比沒加索引快3倍以上。

 

9、分析表和索引的語句

 

analyze table  TABLE_NAME compute statistics 

select '  analyze index '||index_name ||' compute statistics ;' from user_indexes ui where ui.table_name='TABLE_NAME ' ;     

 

  1. 判斷索引有效和無效

select ui.index_name,status  from user_indexes ui   where table_name='LIS_RESULT'      

 

說明:如果STATUS爲VALID那麼索引爲有效。UNUSABLE爲無效。

如果手工將索引 IDX_LIS_RESULT1 設爲無效 可以如下操作:

alter index IDX_LIS_RESULT1 unusable; 

 

備註說明:文章中table_name是目標庫查詢的主表。其他小數據量的表可以不查詢碎片。

發佈了18 篇原創文章 · 獲贊 13 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章