ORACLE查询优化
2016-03-15 00:00
260 查看
摘要: ORACLE查询优化
ORACLE查询优化:
症结:
目前项目数据库查询速度太慢,130W的数据分页查询页面请求直接超时,拿语句到PLSQL进行查询,超30秒,不能忍,直接点终止查询了。
针对目前查询速度的优化思路及方案:
拿到查询的SQL到手后,先去掉关联表后,直接业务主表单表查询,发现只少了十几秒左右,看来一半问题在于主表。
不多说直接看查询计划,发现 SORT ORDER BY TABLE ACCESS FULL ,ok,去掉order by 后查询1秒多,症结找到!
A. 首先想到的是oracle排序空间是否足够,Oracle排序是在PGA中进行的,当PGA的内存不足时,则需要使用到临时表空间,
使用临时表空间,会急剧的加大IO,从而降低整个排序的性能。所以,如果条件允许,尽量加大PGA的大小,让整个排序过程在内存中完成。
这个简单,发现sort_area_size值还是默认的64KB大小,同时查看一下是否占用了disk sorts ,并相应增加sort_area_size参数值
直到显示为 0 sorts (disk)
B.然后思考解决办法,首先关联表太多,导致损耗十几秒时间,首先想到的是查改分离,
1. 先建立查询表,只保留查询结果需要的字段,新增加一个数值类型的主键字段,同时对应增加一个SEQ
2. 数据先排序后,再批量导入,主键将按照排序后的SEQ生成对应主键
3. 在业务主表增加相应的触发器(新增,修改,删除),业务表变动触发同步到查询表
结果:
业务单表order by 查询 15秒左右浮动
查询单表按照主键 order by 查询 0.002秒左右浮动
跟踪查询计划变为 COUNT STOPKEY TABLE -- ACCESS BY INDEX ROWID -- INDEX FULL SCAN
这才是想要的,可见table full 的消耗何其恐怖...
C.最后就是加上分页了
SELECT * FROM (
SELECT ROWNUM AS ROWN,DB.* FROM (
SELECT * FROM TABLE
ORDER BY PK_COL
) DB
) TEMPDB WHERE 1=1 AND TEMPDB.ROWN > 0 and tempdb.rown <= 10
一执行,需要4秒左右,WHY?,不加分页就执行里面那句可是毫秒级别的查询反馈,继续查看执行计划,发现又是万恶的 TABLE FULL
其实大家眼尖的已经发现了,分页不是这么写的,不描述的直接上代码:
SELECT * FROM (
SELECT ROWNUM AS ROWN,DB.* FROM (
SELECT * FROM TABLE
WHERE ROWNUM <=10
ORDER BY PK_COL
) DB
) TEMPDB WHERE 1=1 AND TEMPDB.ROWN > 0
很好继续跑到毫秒级,到这里就结束了。
最后COUNT(1)一遍再加上select * 一遍 加起来在PLSQL执行都只要20几毫秒,
集成到项目上测试,耗时5秒左右,这就不是我能控制的了,但至少操作等待时间还勉强能接收,页面不会挂掉了.
ORACLE查询优化:
症结:
目前项目数据库查询速度太慢,130W的数据分页查询页面请求直接超时,拿语句到PLSQL进行查询,超30秒,不能忍,直接点终止查询了。
针对目前查询速度的优化思路及方案:
拿到查询的SQL到手后,先去掉关联表后,直接业务主表单表查询,发现只少了十几秒左右,看来一半问题在于主表。
不多说直接看查询计划,发现 SORT ORDER BY TABLE ACCESS FULL ,ok,去掉order by 后查询1秒多,症结找到!
A. 首先想到的是oracle排序空间是否足够,Oracle排序是在PGA中进行的,当PGA的内存不足时,则需要使用到临时表空间,
使用临时表空间,会急剧的加大IO,从而降低整个排序的性能。所以,如果条件允许,尽量加大PGA的大小,让整个排序过程在内存中完成。
这个简单,发现sort_area_size值还是默认的64KB大小,同时查看一下是否占用了disk sorts ,并相应增加sort_area_size参数值
直到显示为 0 sorts (disk)
B.然后思考解决办法,首先关联表太多,导致损耗十几秒时间,首先想到的是查改分离,
1. 先建立查询表,只保留查询结果需要的字段,新增加一个数值类型的主键字段,同时对应增加一个SEQ
2. 数据先排序后,再批量导入,主键将按照排序后的SEQ生成对应主键
3. 在业务主表增加相应的触发器(新增,修改,删除),业务表变动触发同步到查询表
结果:
业务单表order by 查询 15秒左右浮动
查询单表按照主键 order by 查询 0.002秒左右浮动
跟踪查询计划变为 COUNT STOPKEY TABLE -- ACCESS BY INDEX ROWID -- INDEX FULL SCAN
这才是想要的,可见table full 的消耗何其恐怖...
C.最后就是加上分页了
SELECT * FROM (
SELECT ROWNUM AS ROWN,DB.* FROM (
SELECT * FROM TABLE
ORDER BY PK_COL
) DB
) TEMPDB WHERE 1=1 AND TEMPDB.ROWN > 0 and tempdb.rown <= 10
一执行,需要4秒左右,WHY?,不加分页就执行里面那句可是毫秒级别的查询反馈,继续查看执行计划,发现又是万恶的 TABLE FULL
其实大家眼尖的已经发现了,分页不是这么写的,不描述的直接上代码:
SELECT * FROM (
SELECT ROWNUM AS ROWN,DB.* FROM (
SELECT * FROM TABLE
WHERE ROWNUM <=10
ORDER BY PK_COL
) DB
) TEMPDB WHERE 1=1 AND TEMPDB.ROWN > 0
很好继续跑到毫秒级,到这里就结束了。
最后COUNT(1)一遍再加上select * 一遍 加起来在PLSQL执行都只要20几毫秒,
集成到项目上测试,耗时5秒左右,这就不是我能控制的了,但至少操作等待时间还勉强能接收,页面不会挂掉了.
相关文章推荐
- 第六章 使用数字
- 37.Oracle深度学习笔记——RAC的相关等待事件
- Oracle 10g实现存储过程异步调用
- 扒扒数据库长长知识(下载资源组合看)之 00(oracle简介)
- oracle基本总结
- Oracle存储过程中异步调用的实际操作步骤
- linux内核参数Oracle相关调整(网摘)
- 【转】ORACLE快速彻底Kill掉的会话
- Oracle基本语法知识点
- Hibernate与Oracle数据库的连接
- Oracle同义词创建及分配用户创建同义词权限
- MyEclipse关联Oracle数据库
- oracle——SQL复习02
- 工作记录:oracle数据库移机中关于redolog出错的处理
- 简单java连接oracle,Statement,PreparedStatement,CallableStatement操作
- 工作记录:rman备份恢复融合平台oracle数据库到异机服务器
- oracle中从指定日期中获取月份或者部分数据
- Oracle定时执行计划任务
- oracle表连接方式对比
- ORACLE11g 实例启动报错 ORA-00205: error in identifying control file, check alert log for more info