Oracle数据库该如何着手优化一个SQL

这是个终极问题,因为优化本身的复杂性实在是难以总结的,很多时候优化的方法并不是用到了什么高深莫测的技术,而只是一个思想意识层面的差异,而这些都很可能连带导致性能表现上的巨大差异。
所以有时候我们应该先搞清楚需求到底是什么,SQL本身是否合理,这些思考很可能会使优化工作事半功倍。而本文是假设SQL本身合理,从Oracle提供给我们的一些技术手段来简单介绍下Oracle数据库,该如何使用一些现有的技术来优化一个SQL执行的性能。

  1. 确定需要优化的SQL文本及当前SQL执行计划
  2. 确定SQL涉及的所有表及其索引的相关信息
  3. 运行SQL Tuning Advisor 得到调整建议供优化参考
  4. 收集表信息
  5. 收集索引信息
  6. SQL Profile
  7. 物化视图

1. 确定需要优化的SQL文本及当前SQL执行计划

优化之前先确定好需要优化的SQL文本以及当前SQL的执行计划是什么样,注意PL/SQL Developer这类工具F5看到的执行计划很可能并不准确。
相关内容参考:

2. 确定SQL涉及的所有表及其索引的相关信息

确定查询涉及到的所有表及其索引的相关基础信息。比如:

各表的数据量
表和索引类型
表分区信息,每个分区的数据量
索引字段
索引分区信息
表关联方式
结果集的数量

确定相关信息,以T2表为例:

--普通表/分区表信息
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;

相关内容参考:

3. 运行SQL Tuning Advisor 得到调整建议供优化参考

运行SQL Tuning Advisor 得到调整建议供优化参考, SQL Tuning Advisor得到的优化建议仅供参考,具体如何做还需要结合业务实际情况。

相关内容参考:

4. 收集表信息

例如收集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

统计信息加锁/解锁

--锁住表的统计信息
exec dbms_stats.lock_table_stats(‘ZJY‘,‘T2‘);
--解锁表的统计信息
exec dbms_stats.unlock_table_stats(‘ZJY‘,‘T2‘); 

相关内容参考:

5. 收集索引信息

例如只收集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;

6. SQL Profile

SQL Profile是10g中的新特性,作为自动SQL调整过程的一部分。SQL Profile是一个对象,它包含了可以帮助查询优化器为一个特定的SQL语句找到高效执行计划的信息。这些信息包括执行环境、对象统计和对查询优化器所做评估的修正信息。它的最大优点之一就是在不修改SQL语句和会话执行环境的情况下影响查询优化器的决定。SQL Profile中包含的并非单个执行计划的信息,SQL Profile不会固定一个SQL语句的执行计划。当表的数据增长或者索引创建、删除,使用同一个SQL Profile的执行计划可能会改变,而存储在SQL Profile中的信息会继续起作用。所以,经过一段很长的时间之后,它的信息有可能会过时,需要重新生成。

相关内容参考:

7. 物化视图

Oracle的物化视图可以用于预先计算并保存(表连接或聚集等耗时较多的操作的)结果,所以合理使用物化视图,会在执行查询时避免进行这些耗时的操作,从而快速的得到结果。

相关内容参考:

时间: 2024-10-14 20:16:37

Oracle数据库该如何着手优化一个SQL的相关文章

oracle数据库一些常用的优化方案

充分利用系统全局区域SGA(SYSTEM GLOBAL AREA) :     SGA是oracle数据库的心脏.用户的进程对这个内存区发送事务,并且以这里作为高速缓存读取命中的数据,以实现加速的目的.正确的SGA大小对数据库的性能至关重要. SGA包括以下几个部分: 1. 数据块缓冲区(data block buffer cache)是SGA中的一块高速缓存,占整个数据库大小的1%-2%,用来存储从数据库重读取的数据块(表.索引.簇等),因此采用least recently used (LRU

Oracle 12C 某电信公司 优化一个12小时跑不出来的SQL,最后6分钟就跑完了

今天一个网友找我帮他优化他负责数据库的SQL,客服反映这个SQL 跑很久,跑了12个小时,最后跑出ORA-01555 ,以报错结束了这个慢SQL的生命.找我帮他优化,OK ,义不容辞. 他们那边数据库环境是Oracle 12C的: 原SQL 及其执行计划为: explain plan for select count(*) from (select A.service_code, A.accNo, A.phone_no, A.account_type, nvl(B.mtNo, 0) mt fro

Oracle数据库概念和一些基本的SQL语句

1.数据 定义:描述事物的符号.例如:文本.音频.视频都是数据. 2.数据库 存放数据的仓库,存放在计算机中,按照一定格式存放,可以为用户共享. 3.数据库的发展阶段 1.网状数据库 2.层次数据库 3.关系数据库(目前主流数据库) 4.对象数据库 4.NOSQL数据库 4.Oracle数据库系统用户(管理员) scott账户:测试账户,练习账户 登录方式:dos命令行---->sqlplus--->输入账户:scott--->输入密码---->(登录成功) 如果该账户被锁定,需要

Oracle数据库软件标准版的一个限制:只能用一个rman channel

Restrictions in "Standard Edition" Rman channel allocation does not allow parallelism/having multiple channels allocated. 来源于: RMAN DUPLICATE FROM 'ACTIVE DATABASE' in "Standard Edition" fails with RMAN-6181 (文档 ID 1265014.1) 版权声明:本文为博

Oracle数据库软件标准版的一个限制:仅仅能用一个rman channel

Restrictions in "Standard Edition" Rman channel allocation does not allow parallelism/having multiple channels allocated. 来源于: RMAN DUPLICATE FROM 'ACTIVE DATABASE' in "Standard Edition" fails with RMAN-6181 (文档 ID 1265014.1)

PL/SQL连接oracle数据库

PL/SQL连接oracle数据库 1.简单介绍 在不安装oracle数据库的情况下使用pl/sql连接远程oracle数据库. 2.详细步骤: a)      安装PL/SQL.依据自己的操作系统安装oracleclient(跟oracle数据库的版本号没有关系). b)     设置连接远程oracle数据库的连接信息.三种方式(主要是在tnsnames.ora文件里加入?远程数据库连接信息).以下三种方式在文件最后追加的内容是依据我自己的数据库连接信息追加的.仅做參考: i.     安装

Oracle数据库常用SQL

Oracle数据库创建实例的过程类似于Sql server创建数据库,Oracle一个实例可以对应多个表空间,一个表空间对应一个用户,根据不同的用户名.密码登录不同的表空间. 因此,创建表空间后,紧接着要创建用户并为其指定表空间.并授权给该用户,一般是connect.resource.dba权限 grant connect,resource,dba to yun 查询数据库名称: select name from v$database; 怎样查得数据库的sid.系统环境变量 select nam

《Oracle数据库的SQL分页模板》

在系统开发过程中,需要对数据进行查询,大部分情况下从数据库中查询的数据量比较大,在系统页面无法全部显示,而且查询全部的数据会影响系统的反应速度,需要对所查询的数据进行分页的查询操作,以此减轻系统的压力. 在Oracle数据库中,如何完成分页SQL的编写,影响着系统开发的速度,特提供两个SQL的分页模板: (1).采用oracle的内置函数ROWNUM.(ROWNUM是结果的伪列,仅仅当聚集结果时产生,但早于排序或聚合) select <columns I actually want>,rown

oracle数据库tns配置方法详解

TNS简要介绍与应用 Oracle中TNS的完整定义:transparence Network Substrate透明网络底层,监听服务是它重要的一部分,不是全部,不要把TNS当作只是监听器. TNS是Oracle Net的一部分,专门用来管理和配置Oracle数据库和客户端连接的一个工具,在大多数情况下客户端和数据库要通讯,必须配置TNS,当然在少数情况下,不用配置TNS也可以连接Oracle数据库,比如通过JDBC.如果通过TNS连接Oracle,那么客户端必须安装Oracle client