這是個終極問題,由於優化自己的複雜性實在是難以總結的,不少時候優化的方法並非用到了什麼高深莫測的技術,而只是一個思想意識層面的差別,而這些都極可能連帶致使性能表現上的巨大差別。
因此有時候咱們應該先搞清楚需求究竟是什麼,SQL自己是否合理,這些思考極可能會使優化工做事半功倍。而本文是假設SQL自己合理,從Oracle提供給咱們的一些技術手段來簡單介紹下Oracle數據庫,該如何使用一些現有的技術來優化一個SQL執行的性能。html
優化以前先肯定好須要優化的SQL文本以及當前SQL的執行計劃是什麼樣,注意PL/SQL Developer這類工具F5看到的執行計劃極可能並不許確。
相關內容參考:sql
肯定查詢涉及到的全部表及其索引的相關基礎信息。好比:數據庫
各表的數據量
表和索引類型
表分區信息,每一個分區的數據量
索引字段
索引分區信息
表關聯方式
結果集的數量工具
肯定相關信息,以T2表爲例:oop
--普通表/分區表信息 select * from dba_tables where table_name = 'T2'; select * from dba_part_tables where table_name = 'T2'; --普通表/分區表的每一個分區大約__G大小 select (t.bytes/1024/1024) "MB", t.* from dba_segments t where segment_name = 'T2'; --表數據量信息 --普通表的數據量 select count(1) from T2; --____數據左右 --分區表的某個分區數據量 select count(*) from T2 partition(P20160101); --____數據左右 select count(*) from T2 partition(P20160102); --表索引信息 --普通表索引及各個索引的索引列 select * from dba_indexes where table_name = 'T2'; select * from dba_ind_columns where index_name in (select index_name from dba_indexes where table_name = 'T2')order by index_name, column_position; --分區表索引及各個索引的索引列 select * from dba_part_indexes where table_name = 'T2'; select * from dba_ind_columns where index_name in (select index_name from dba_part_indexes where table_name = 'T2') order by index_name, column_position; --索引段大小信息 --select (t.bytes/1024/1024) "MB", t.* from dba_segments t where segment_name in (select index_name from dba_part_indexes where table_name = 'T2') order by segment_name, partition_name;
相關內容參考:性能
運行SQL Tuning Advisor 獲得調整建議供優化參考, SQL Tuning Advisor獲得的優化建議僅供參考,具體如何作還須要結合業務實際狀況。優化
相關內容參考:spa
例如收集ZJY用戶下T2表的統計信息。(T2是range分區表,按天分區,天天數據量大概80w,存放半年)日誌
SQL> execute dbms_stats.gather_table_stats(ownname => 'ZJY', tabname => 'T2', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE AUTO', cascade => TRUE, degree => 16); PL/SQL procedure successfully completed Executed in 5896.641 seconds
統計信息加鎖/解鎖code
--鎖住表的統計信息 exec dbms_stats.lock_table_stats('ZJY','T2'); --解鎖表的統計信息 exec dbms_stats.unlock_table_stats('ZJY','T2');
相關內容參考:
例如只收集ZJY用戶下T2表的索引IDX_T2_1統計信息。(IDX_T2_1是分區索引,包含4個字段)
SQL> execute dbms_stats.gather_index_stats(ownname => 'ZJY', indname => 'IDX_T2_1', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, degree => 8); PL/SQL procedure successfully completed Executed in 44.312 seconds
有時還極可能須要在業務閒時在線建立新的索引
--不記錄日誌在線並行建立單列索引IDX_T2_2(並行度視生產環境當前的CPU資源使用狀況來肯定合理的值) create index IDX_T2_2 on T2(start_time) tablespace DBS_I_JINGYU nologging parallel 12 online; alter index IDX_T2_2 noparallel; alter index IDX_T2_2 logging;
SQL Profile是10g中的新特性,做爲自動SQL調整過程的一部分。SQL Profile是一個對象,它包含了能夠幫助查詢優化器爲一個特定的SQL語句找到高效執行計劃的信息。這些信息包括執行環境、對象統計和對查詢優化器所作評估的修正信息。它的最大優勢之一就是在不修改SQL語句和會話執行環境的狀況下影響查詢優化器的決定。SQL Profile中包含的並不是單個執行計劃的信息,SQL Profile不會固定一個SQL語句的執行計劃。當表的數據增加或者索引建立、刪除,使用同一個SQL Profile的執行計劃可能會改變,而存儲在SQL Profile中的信息會繼續起做用。因此,通過一段很長的時間以後,它的信息有可能會過期,須要從新生成。
相關內容參考:
Oracle的物化視圖能夠用於預先計算並保存(錶鏈接或彙集等耗時較多的操做的)結果,因此合理使用物化視圖,會在執行查詢時避免進行這些耗時的操做,從而快速的獲得結果。
相關內容參考: