实例分析ORACLE数据库性能优化

ORACLE数据库的优化方式和MYSQL等很大的区别,今天通过一个ORACLE数据库实例从表格、数据等各个方便分析了如何进行ORACLE数据库的优化。

tsfree.sql视图

这个sql语句迅速的对每一个表空间中的空间总量与每一个表空间中可用的空间的总量进行比较

表空间是数据库的逻辑划分,一个表空间只能属于一个数据库。所有的数据库对象都存放在指定的表空间中。但主要存放的是表, 所以称作表空间。

SELECT FS.TABLESPACE_NAME "Talbspace",
(DF.TOTALSPACE - FS.FREESPACE) "Userd MB",
FS.FREESPACE "Free MB",
DF.TOTALSPACE "Total MB",
ROUND(100 * (FS.FREESPACE / DF.TOTALSPACE)) "Pct Free" FROM
(SELECT TABLESPACE_NAME, ROUND(SUM(BYTES) / 1048576) TOTALSPACE FROM
DBA_DATA_FILES GROUP BY TABLESPACE_NAME) DF,
(SELECT TABLESPACE_NAME, ROUND(SUM(BYTES) / 1048576) FREESPACE
FROM DBA_FREE_SPACE
GROUP BY TABLESPACE_NAME) FS WHERE DF.TABLESPACE_NAME = FS.TABLESPACE_NAME;

varray 表的使用

CREATE OR REPLACE TYPE EMPLOYER_NAME AS OBJECT (E_NAME VARCHAR(40));

CREATE OR REPLACE TYPE PRIOR_EMPLOYER_NAME_ARR AS VARRAY(10) OF
EMPLOYER_NAME;

CREATE OR REPLACE TYPE FULL_MAILLING_ADRESS_TYPE AS OBJECT(STREET
VARCHAR2(80), CITY VARCHAR2(80), STATE CHAR(2), ZIP VARCHAR2(10));

CREATE OR REPLACE TYPE EMPLOYEE AS OBJECT(LAST_NAME VARCHAR(40),
FULL_ADDRESS FULL_MAILLING_ADRESS_TYPE, PRIOR_EMPLOYERS
PRIOR_EMPLOYER_NAME_ARR);

CREATE TABLE EMP OF EMPLOYEE;

INSERT INTO EMP VALUES('Jim', FULL_MAILLING_ADRESS_TYPE('Airplan Ave', 'Rocky', 'NC', '2343'), PRIOR_EMPLOYER_NAME_ARR(EMPLOYER_NAME('IBM'), EMPLOYER_NAME('APPLE'), EMPLOYER_NAME('CNN')));

-- 回滚

DROP TYPE PRIOR_EMPLOYER_NAME_ARR FORCE;
DROP TYPE FULL_MAILLING_ADRESS_TYPE FORCE;
DROP TYPE EMPLOYEE FORCE;
DROP TYPE EMPLOYER_NAME FORCE;
DROP TABLE EMP;
COMMIT;
SELECT P.LAST_NAME, PRIOR_EMPLOYERS.*
FROM EMP P, TABLE(P.PRIOR_EMPLOYERS) PRIOR_EMPLOYERS
WHERE P.LAST_NAME = 'Jim';

SQL 执行过程

1,检查安全性,确保sql数据执行者有权限执行
2,检查sql语法
3,可能发生的查询重新书写
4,执行

创建执行计划
生产器接受经过解析的sql
捆绑执行计划 执行执行计划 读取结果记录 排序结果集

数据访问方式:

1,全表扫描 db_file_multiblock_read_count = 128
一次性最大读取block的数量
Oracle开启并行: Alter table employee parallel degree 35;
 顺序读取,直到结尾
1,当表中不存在索引
2,查询中不包含where字句
3,内置函数中的索引无效
4,like操作 %开头
5,使用基于成本优化器 数据量少时
6,当初始化文件中存在optimizer_mode = all_rows
7,负向条件查询不能使用索引 例如 status != 0, not in, not exists 可以优化为 in (2,3);

下列情况的SQL语句会导致全表扫:

1,使用null条件查询导致全表扫,因为索引不能为空
为了绕过全表扫这个问题,可以采取这样的方法
update emp set name = 'N/A' where name is null;
select name from emp where name = 'N/A';
2,对没有索引的字段查询,找到where条件后面的查询不带索引的字段,加索引可以
大大提高查询性能。
3,带有like条件的查询 like '%x%' 全表扫描,like 'x%' 不会全表扫,因为like
以字符开始。
4,内置的函数使索引无效,对于Date类型的数据来说非常的严重
内置函数 (to_date,to_char)
如果没有创建与内置函数匹配的基于函数的索引,那么这些函数通常会导致sql优化器全表扫描
select name from emp where date < sysdate -8;
检查where子句脚本是否含有 substr to_char decode
SELECT SQL_TEXT, DISK_READS, EXECUTIONS, PARSE_CALLS
FROM V$SQLAREA
WHERE LOWER(SQL_TEXT) LIKE '%substr%'
OR LOWER(SQL_TEXT) LIKE '%to_char%'
OR LOWER(SQL_TEXT) LIKE '%decode%'
ORDER BY DISK_READS DESC;
使用函数索引解决这个问题

5,all_rows 优化器目标是提高吞吐量而且倾向于使用全表扫描,因此 对于任何一
个要求sql快速查询返回部分结果集而言,optimizer_mode
应该设置为first_rows

6,经验上,能过滤80%数据时就可以使用索引,对于订单状态,如果状态很少,不宜
使用索引,如果状态值很多可以使用索引。

7,如果查询字段大部分是单条数据查询,使用Hash索引性能更好
原因:B-TREE 索引的时间复杂度是O(log(n))
Hash 索引的时间复杂度是O(1)

8,符合索引最左前缀,例如建立符合索引(passWord,userName)
select * from user u where u.pass_word = ? and u.user_name = ? 可以命中索引
select * from user u where u.user_name = ? and u.pass_word= ? 可以命中索引
select * from user u where u.pass_word = ? 可以命中索引
select * from user u where u.user_name = ? 不可以命中索引

如何找出影响力高的sql语句

 视图 v$sqlarea ,下列参数按照重要性从高到低排序
 executions :越经常执行的sql语句就应当越早的调整,因为它会对整体的性能产生巨大的影响。
 disk_reads: 磁盘读取,高的磁盘读取量可能表明查询导致过多的输入输出量。
 rows_processed:记录处理,处理大量的记录的查询会导致较大的输入输出量,同时在排序的时候对TEMP表空间产生影响。
 buffer_gets:缓冲区读取,高的缓冲读取量可能表明了一个高资源使用量的查询。
 sorts:排序会导致速度的明显减低,尤其是在TEMP表空间中进行的排序。

2.赛列获取

Oracle对单表簇和多表簇进行散列存储,用来在连接操作中减低输入 输出

3,ROWID 访问

通过Rowid访问单条数据最快的方式,在实际的引用中,首先从索引中收集ROWID,然后通过ROWID进行数据读取

索引访问方式

索引都可以看做一组符合主键和ROWID的组合,索引访问的目的是收集对目标快速读取时所需要的ROWID

B树索引,位图索引 基于函数的索引.

索引范围扫描:读取一个或者多个ROWID 索引数值升序排列

eg:select * from table where a = 'a';

快速全索引扫描

eg: select distinct color,count(*) from table group by color;

单个索引扫描:读取一个单独的ROWID

降序索引范围扫描:读取一个或者多个ROWID 索引数值降序排列

AND - EQUALS: select * from table where a = 'a' and b > 34; 从where字句中收集多个ROWID

连接操作

嵌套循环连接

散列连接

散列连接通常快于嵌套循环连接,特别是在驱动表以及在查询的where子句中过滤,只剩下少量的记录的情况下

排序合并连接

连接提示:

表反向连接提示,例如,NOT IN, NOT EXISTS
尽量避免使用 NOT IN 子句(它将调用子查询),而应该使用NOT EXISTS 子句(它将调用相关联的子查询),
因为如果子查询返回的任何一条记录中包含空值,那么该查询将不会返回记录,如果允许NOT IN 子句查询为空,那么
这种查询的性能非常的低,子查询会在外层查询块中对每一条记录重新执行一次。

排序大小 sort_area_size_init.ora 参数,在控制台查看 sort_area_size;

查询语句:show parameter sort_area_size;

磁盘排序的执行速度要比内存排序的的执行速度慢14000倍

磁盘排序之所以昂贵,有以下几个原因:

1,同在内存中进行排序比较,速度太慢
2,磁盘排序耗费临时表空间的资源

数据库分配2个临时表空间:

select DEFAULT_TABLESPACE, TEMPORARY_TABLESPACE from dba_users where username='SYS';

select * from dba_temp_free_space;

Oracle临时表空间主要充当两个主要作用:临时表数据段分配和排序汇总溢出段。

排序汇总溢出的范围比较广泛。我们在SQL语句中进行order by/group by等操作,

首先是选择PGA的内存sort area、hash area和bitmap area。

如果SQL使用排序空间很高,单个server process对应的PGA不足以支撑排序要求的时候,临时表空间会充当排序段的数据写入。

而磁盘排序会降低单个任务的速度,同时还会影响Oracle实例中正在执行的其他任务,而且过多的磁盘排序将导致过多的空闲缓冲等待

以及将其他任务的数据块从缓冲池中分页出去的昂贵代价。

Oracle首先尝试在sort_area_size 分配的内存区中进行排序,Oracle只有不能再内存中排序时,才会调用磁盘排序
并将内存框架迁移到TEMP表空间,继续进行排序。

使用索引范围扫描的总体原则

 -- 对于原始排序的表, 仅读取少于40%的表记录查询就应该使用索引范围扫描,反之,多余40%,使用全表扫。
 -- 对于未排序的表, 仅读取少于7%的表记录查询就应该使用索引范围扫描,反之,多余7%,使用全表扫。

表的访问方式

sql优化器

对于任何一个sql语句来说,存在唯一的优化表访问方式,而你的工作就是找到这种方式,并且长期使用它。

db_file_multiblock_read_count

目的是为sql语句生成最快 并且好资源最少的执行计划

1,基于规则的优化器

步骤
对于在where子句中的每一个表
-- 生成一个可行的执行计划列表,这个列表中列出所有可以用来访问表的路径
-- 为每一个执行计划指定级别数值
-- 选择级别数值最低的计划
-- 对结果集的选择级别最低 连接方法进行评估

基于规则优化器(PBO)特征
- 总是使用索引,使用索引永远比使用全表扫描或使用排序合并连接(排序合并连接不需要索引)更加可取
- 总是从驱动表开始 在from字句的最后一个表是驱动表,在这个表中选择的记录数应该是最少(查询返回值最少),RBO在执行嵌套循环连接
操作时,将这个驱动表作为第一个操作表。
- 只有在不可避免的情况下才使用全表扫描
-任何索引都可以
- 有时越简单越好
 

2,基于成本的优化器(CBO)

 基于规则优化提供更加复杂的优化替代方案
 ANALYZE TABLE TT_TCAS_HK_QTY COMPUTE STATISTICS;
 ANALYZE TABLE TT_TCAS_HK_QTY ESTIMATE STATISTICS SAMPLE 5000 ROWS;
 ANALYZE TABLE TT_TCAS_HK_QTY ESTIMATE STATISTICS SAMPLE 5000 ROWS FOR ALL INDEXED COLUMNS;

 CBO在以下情况会选择错误的全表扫描
 1,最高峰值过高
 2,错误的optimizer_mode,如果optimizer_mode设置为all_rows,choose,那么sql优化器会倾向于使用全表扫描。
 3,多表连接,存在多余3张表连接时,即使连接中存在索引,cbo仍然会对这些表进行全表扫描。
 4,不平衡的索引分布,比如 color = 'blue' color字段上有索引,但是只有1%的记录属于blue,

SQL 的SGA统计资料

select name,value from v$sysstat where name like 'table%'

table scans(short table) -- 对小表全表扫描的次数

table scans(long table) -- 对大表全表扫描的次数,评估是否通过加索引减少大表的扫描次数 或者通过调用Oracle并行(opq)来提高查询的执行速度。

table scans Rows Gotten -- 这个数目说明全表扫描扫描记录条数

table scans blocks Gotten -- 扫描获取数据库的数目

Table fetch by rowid -- 通过索引访问记录的数目,这里的索引通常是嵌套循环连接

table fetch by Continued Row -- 这个数目说明与其他数据块连接在一起的记录数目

程序库缓存中可以多次使用的SQL

Oracle在辨认"相同的"sql语句是存在问题

例如:select from customer; Select From Customer; 尽管区别字母的大小写,Oracle会对第二个sql语句进行重新编译执行;

(0)

相关推荐

  • Oracle之SQL语句性能优化(34条优化方法)

    好多同学对sql的优化好像是知道的甚少,最近总结了以下34条仅供参考. (1)选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表. (2) WH

  • Oracle数据库中基本的查询优化与子查询优化讲解

    1. 查询条件合理排序 Oracle采用自下而上的顺序解析WHERE字据,从优化性能角度考虑,建议将那些可以过滤掉大量记录行的条件写在WHERE子句的末尾,而将表 之间的连接条件置于其他WHERE子句之前,即对易排查的条件先做判断处理,这样在过滤掉尽可能多的记录后再进行等值连接,可以提高检索效率. 例如: SELECT empno, ename, job, sal, dept.deptno, dname FROM emp, dept WHERE emp.deptno = dept.deptno

  • Oracle查询优化日期运算实例详解

     加减日.月.年 在Oracle中,date类型可以直接加减天数,而加减月份要用add_months函数. select a.hiredate 雇用日期, a.hiredate + 5 加5天, a.hiredate - 5 减5天, add_months(hiredate, 5) 加5个月, add_months(hiredate, -5) 减5个月, add_months(hiredate, 5 * 12) 加5年, add_months(hiredate, -5 * 12) 减5年 fro

  • Oracle监听器被优化大师挂掉后的完美解决方法

    Oracle监听器被优化大师挂掉后的解决方法: 在启动oracleorahome90tnslistener服务 时出错,信息: 在本地计算机无法启动oracleorahome90tnslistener服务, 错误3:系统找不到指定路径. 我在网上查资料后,发现一般这些文件的位置由注册表的 ORACLE_HOME 变量决定. 先看一看注册表中 HKEY_LOACL_MACHINE/ SOFTWARE/ORACLE 下的 ORACLE_HOME值 如果没有这个值 ,那你一定要添加进去. ORACLE

  • Oracle分页查询性能优化代码详解

    对于数据库中表的数据的 Web 显示,如果没有展示顺序的需要,而且因为满足条件的记录如此之多,就不得不对数据进行分页处理.常常用户并不是对所有数据都感兴趣的,或者大部分情况下,他们只看前几页. 通常有以下两种分页技术可供选择. Select * from ( Select rownum rn,t.* from table t) Where rn>&minnum and rn<=&maxnum 或者 Select * from ( Select rownum rn,t.* fro

  • 整理Oracle数据库中数据查询优化的一些关键点

    数据库最基本的任务是存储.管理数据,而终端用户唯一能看到的数据库特性就是其性能:数据库以何速度处理某一指定查询的结果,并且将结果返回到用户所用的工具和应用程序.从大多数系统的应用实例来看,查询操作在各种数据库操作中所占据的比重最大.查阅新闻. 查看文件. 查询统计信息等.因此,数据库查询操作的效率是影响一个应用系统响应时间的关键因素.随着一个应用系统中数据的动态增长,数据量变大,数据库查询效率就会有所降低,应用系统的响应速度也随之减慢,尤其对于海量数据的管理和查询问题就更加突出,Oracle查询

  • 一些Oracle数据库中的查询优化建议综合

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引.   2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: select id from t where num=0 3.应尽量避免在 where 子句中使用!=或<>操作符,否则将引

  • ORACLE SQL语句优化技术要点解析

    操作符优化: IN 操作符 用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格. 但是用IN的SQL性能总是比较低的,从ORACLE执行的步骤来分析用IN的SQL与不用IN的SQL有以下区别: ORACLE试图将其转换成多个表的连接,如果转换不成功则先执行IN里面的子查询,再查询外层的表记录,如果转换成功则直接采用多个表的连接方式查询. 由此可见用IN的SQL至少多了一个转换的过程.一般的SQL都可以转换成功,但对于含有分组统计等方面的SQL就不能转换了. 推荐方案:

  • Oracle数据库中SQL语句的优化技巧

    在SQL语句优化过程中,我们经常会用到hint,现总结一下在SQL优化过程中常见Oracle HINT的用法: 1. /*+ALL_ROWS*/ 表明对语句块选择基于开销的优化方法,并获得最佳吞吐量,使资源消耗最小化. 例如: SELECT /*+ALL+_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT'; 2. /*+FIRST_ROWS*/ 表明对语句块选择基于开销的优化方法,并获得最佳响应时间,使资源消耗最小化.

  • 实例分析ORACLE数据库性能优化

    ORACLE数据库的优化方式和MYSQL等很大的区别,今天通过一个ORACLE数据库实例从表格.数据等各个方便分析了如何进行ORACLE数据库的优化. tsfree.sql视图 这个sql语句迅速的对每一个表空间中的空间总量与每一个表空间中可用的空间的总量进行比较 表空间是数据库的逻辑划分,一个表空间只能属于一个数据库.所有的数据库对象都存放在指定的表空间中.但主要存放的是表, 所以称作表空间. SELECT FS.TABLESPACE_NAME "Talbspace", (DF.TO

  • Oracle数据库性能优化技术开发者网络Oracle

    正在看的ORACLE教程是:Oracle数据库性能优化技术开发者网络Oracle.介绍:细处着手,巧处用功.高手和菜鸟之间的差别就是:高手什么都知道,菜鸟知道一些.电脑小技巧收集最新奇招高招,让你轻松踏上高手之路.  摘要: Oracle数据库是当前应用最广泛的大型数据库之一,而其性优化直接关系到系统的运行效率.本文以数据库性能优化的基本原则为出发点,阐述了在数据库设计阶段如何避免竞争和如何优化数据访问,在数据库运行阶段如何从操作系统和数据库实例级别上调整内存和I/O来达到数据库性能优化的各种技

  • Mysql数据库性能优化一

    今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能.这里,我们不会讲过多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库. mysql的性能优化无法一蹴而就,必须一步一步慢慢来,从各个方面进行优化,最终性能就会有大的提升. Mysql数据库的优化技术 对mysql优化是

  • Oracle SQL性能优化系列学习二

    正在看的ORACLE教程是:Oracle SQL性能优化系列学习二.  4. 选择最有效率的表名顺序(只在基于规则的优化器中有效) ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(

  • Oracle SQL性能优化系列学习一

    正在看的ORACLE教程是:Oracle SQL性能优化系列学习一.1. 选用适合的ORACLE优化器 ORACLE的优化器共有3种: a. RULE (基于规则) b. COST (基于成本) c. CHOOSE (选择性) 设置缺省的优化器,可以通过对init.ora文件中OPTIMIZER_MODE参数的各种声明,如RULE,COST,CHOOSE,ALL_ROWS,FIRST_ROWS . 你当然也在SQL句级或是会话(session)级对其进行覆盖. 为了使用基于成本的优化器(CBO,

  • Oracle SQL性能优化系列学习三

    正在看的ORACLE教程是:Oracle SQL性能优化系列学习三.8. 使用DECODE函数来减少处理时间 使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表. 例如: SELECT COUNT(*),SUM(SAL) FROM EMP  WHERE DEPT_NO = 0020  AND ENAME LIKE 'SMITH%'; SELECT COUNT(*),SUM(SAL)  FROM EMP  WHERE DEPT_NO = 0030  AND ENAME LIKE 'SM

  • Mysql数据库性能优化三(分表、增量备份、还原)

    接上篇Mysql数据库性能优化二 对表进行水平划分     如果一个表的记录数太多了,比如上千万条,而且需要经常检索,那么我们就有必要化整为零了.如果我拆成100个表,那么每个表只有10万条记录.当然这需要数据在逻辑上可以划分.一个好的划分依据,有利于程序的简单实现,也可以充分利用水平分表的优势.比如系统界面上只提供按月查询的功能,那么把表按月拆分成12个,每个查询只查询一个表就够了.如果非要按照地域来分,即使把表拆的再小,查询还是要联合所有表来查,还不如不拆了.所以一个好的拆分依据是 最重要的

  • Mysql数据库性能优化之子查询

    记得在做项目的时候, 听到过一句话, 尽量不要使用子查询, 那么这一篇就来看一下, 这句话是否是正确的. 那在这之前, 需要介绍一些概念性东西和mysql对语句的大致处理. 当Mysql Server的连接线程接收到Client发送过来的SQL请求后, 会经过一系列的分解Parse, 进行相应的分析, 然后Mysql会通过查询优化器模块, 根据该Sql所涉及到的数据表的相关统计信息进行计算分析. 然后在得出一个Mysql自认为最合理最优化的数据访问方式, 也就是我们常说的"执行计划",

  • Mysql通过explain分析定位数据库性能问题

    目录 引言 explain基础 exlpain分析实战 总结 引言 数据库性能优化是每个后端程序猿必备的基础技能之一,而Mysql中的explain堪称Mysql的性能优化分析神器,我们可以通过它来分析SQL语句的对应的执行计划在Mysql底层到底是如何执行的,它对于我们评估SQL的执行效率以及确定Mysql的性能优化方向具有重要的意义.但是很多同学对于如何根据explain对已有SQL进行深度的执行分析还是丈二和尚摸不着头脑,因此本文详细阐述通过explain分析定位数据库性能问题. expl

  • MySQL数据库性能优化介绍

    目录 为什么做优化?? 从哪些方面入手?? 解决方案是什么???  要怎样选择??? SQL优化 总结 为什么做优化?? 因为数据量太多了,项目部署上线再到用户使用,每天数据增长几十万条,给服务器带来非常大的负担,互联网一直追求高性能,可是随着业务规模变大,用户数量变多,服务器的性能越来越差,因此我们不得不对数据库有更高要求. 从哪些方面入手?? 第一,是查询的速度,我们期望数据量到达TB级别仍然能够实现百万级别查询速度. 第二.是并发量,我们对它的要求能够同时处理几千甚至上万的并发访问,还要配

随机推荐