这是个终极问题,由于优化自己的复杂性实在是难以总结的,不少时候优化的方法并非用到了什么高深莫测的技术,而只是一个思想意识层面的差别,而这些都极可能连带致使性能表现上的巨大差别。
因此有时候咱们应该先搞清楚需求究竟是什么,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的物化视图能够用于预先计算并保存(表链接或汇集等耗时较多的操做的)结果,因此合理使用物化视图,会在执行查询时避免进行这些耗时的操做,从而快速的获得结果。
相关内容参考: