每天都会看到这样的问题? "我的sql为什么这么慢???" "大侠救命,sql性能问题..." 为什么不先做个查询计划看看呢??? 几点建议: 1. where c.wtpartnumber like '97.%' ------------------------------- 这句究竟能过滤掉多大的数据? 如果过滤不掉很多, 建议调整一下位置. 2. 初始化参数文件中的sort_area_size值是多大,如果排序的 数据量很大,建议调大一些 alter session set sort_area_size=1024000(1M) ... alter session set sort_area_size=10240000(10M) 3. 后边的那些关联列有没有索引? 相关的表是否作过了统计?
谢谢各位大侠! 表如何做统计呢? and a.ida2a2 in ( select max(a.ida2a2) ida2a2 from au3.dqabaselinemaster g, au3.dqabaseline a where g.projectid = f.name and a.ida3masterreference = g.ida2a2 group by a.ida3masterreference )如果没有这句的话整个sql还是不慢的,但是加上去就很慢了,这句有什么问题吗? 感谢!
把效率低的语句抽取出来,单独运行,看看查询计划和运行时间 (set timing on)注意f表在下面的子查询中没有定义,要修改原语句: select max(a.ida2a2) ida2a2 from au3.dqabaselinemaster g, au3.dqabaseline a where g.projectid = f.name and a.ida3masterreference = g.ida2a2 group by a.ida3masterreference新语句: select max(a.ida2a2) ida2a2 from au3.wtdocumentmaster f,au3.dqabaselinemaster g, au3.dqabaseline a where g.projectid = f.name and a.ida3masterreference = g.ida2a2 group by a.ida3masterreference优化器是什么模式? 如果是rbo,要将数据量最小的表放在from 子句的最外层, 作为驱动表.
是choose的;但是里面每个表都有上万的数据,怎么办呢?
25)SELECT STATEMENT, GOAL = CHOOSE 4830 741 80769 24) SORT UNIQUE 4830 741 80769 23) FILTER 15) HASH JOIN 4822 741 80769 1) TABLE ACCESS FULL AU3 DQABASELINE 5 780 7800 14) MERGE JOIN CARTESIAN 4807 14877 1472823 11) HASH JOIN 4769 19 1634 8) NESTED LOOPS 4746 296 20128 5) HASH JOIN 4450 296 17168 2) TABLE ACCESS FULL AU3 WTDOCUMENTMASTER 11 26 1144 4) TABLE ACCESS BY INDEX ROWID AU3 STRINGVALUE 4438 1786 25004 3) INDEX RANGE SCAN AU3 STRINGVALUE$COMPOSITE1 51 1786 7) TABLE ACCESS BY INDEX ROWID AU3 WTPART 1 115741 1157410 6) INDEX UNIQUE SCAN AU3 PK_WTPART 115741 10) TABLE ACCESS BY INDEX ROWID AU3 WTPARTMASTER 22 893 16074 9) INDEX RANGE SCAN AU3 WTPARTMASTER$WTPARTNUMBER 2 893 13) SORT JOIN 4785 783 10179 12) TABLE ACCESS FULL AU3 DQAMILESTONE 2 783 10179 22) FILTER 21) SORT GROUP BY NOSORT 4 1 26 20) NESTED LOOPS 4 3 78 17) TABLE ACCESS BY INDEX ROWID AU3 DQABASELINEMASTER 1 1 16 16) INDEX UNIQUE SCAN AU3 DQABASELINEMASTER$PROJECTID 1 19) TABLE ACCESS BY INDEX ROWID AU3 DQABASELINE 3 780 7800 18) INDEX RANGE SCAN AU3 DQABASELINE$UNIQUE0 2 780 这个整个的explain plan,能看出什么?
不知大家是否喜欢使用‘NOT IN’这样的操作,如果是,那尽量使用(NOT) EXISTS 替代 例子: 语句1 SELECT dname, deptno FROM dept WHERE deptno NOT IN (SELECT deptno FROM emp); 语句2 SELECT dname, deptno FROM dept WHERE NOT EXISTS (SELECT deptno FROM emp WHERE dept.deptno = emp.deptno); 明显的,2要比1的执行性能好很多 因为1中对emp进行了full table scan,这是很浪费时间的操作。而且1中没有用到emp的index, 因为没有where子句。而2中的语句对emp进行的是range scan。
楼主可否格式化一下输出? 先贴出子查询的执行计划,一步一步来.
select max(a.ida2a2) ida2a2 from au3.wtdocumentmaster f, au3.dqabaselinemaster g, au3.dqabaseline a where g.projectid = f.name and a.ida3masterreference = g.ida2a2 group by a.ida3masterreference 相关表和索引最好作一下统计.
每天都会看到这样的问题? "我的sql为什么这么慢???"
"大侠救命,sql性能问题..." 为什么不先做个查询计划看看呢??? 几点建议: 1. where c.wtpartnumber like '97.%'
-------------------------------
这句究竟能过滤掉多大的数据? 如果过滤不掉很多,
建议调整一下位置. 2. 初始化参数文件中的sort_area_size值是多大,如果排序的
数据量很大,建议调大一些 alter session set sort_area_size=1024000(1M)
...
alter session set sort_area_size=10240000(10M) 3. 后边的那些关联列有没有索引? 相关的表是否作过了统计?
表如何做统计呢?
and a.ida2a2 in
(
select max(a.ida2a2) ida2a2 from au3.dqabaselinemaster g, au3.dqabaseline a
where g.projectid = f.name
and a.ida3masterreference = g.ida2a2
group by a.ida3masterreference
)如果没有这句的话整个sql还是不慢的,但是加上去就很慢了,这句有什么问题吗?
感谢!
1.这个语句本身涉及的数据量大,再加group by就更慢了.
2.这个语句的结果集比较大,使得in (...)较慢
3.sql语句用到的各个关键字段上是否有索引?
在 asktom.oracle.com 搜 “max subquery " 有一个很你的情况很象的列子
把效率低的语句抽取出来,单独运行,看看查询计划和运行时间
(set timing on)注意f表在下面的子查询中没有定义,要修改原语句:
select max(a.ida2a2) ida2a2 from au3.dqabaselinemaster g, au3.dqabaseline a
where g.projectid = f.name
and a.ida3masterreference = g.ida2a2
group by a.ida3masterreference新语句:
select max(a.ida2a2) ida2a2 from au3.wtdocumentmaster f,au3.dqabaselinemaster g, au3.dqabaseline a
where g.projectid = f.name
and a.ida3masterreference = g.ida2a2
group by a.ida3masterreference优化器是什么模式? 如果是rbo,要将数据量最小的表放在from 子句的最外层,
作为驱动表.
24) SORT UNIQUE 4830 741 80769
23) FILTER
15) HASH JOIN 4822 741 80769
1) TABLE ACCESS FULL AU3 DQABASELINE 5 780 7800
14) MERGE JOIN CARTESIAN 4807 14877 1472823
11) HASH JOIN 4769 19 1634
8) NESTED LOOPS 4746 296 20128
5) HASH JOIN 4450 296 17168
2) TABLE ACCESS FULL AU3 WTDOCUMENTMASTER 11 26 1144
4) TABLE ACCESS BY INDEX ROWID AU3 STRINGVALUE 4438 1786 25004
3) INDEX RANGE SCAN AU3 STRINGVALUE$COMPOSITE1 51 1786
7) TABLE ACCESS BY INDEX ROWID AU3 WTPART 1 115741 1157410
6) INDEX UNIQUE SCAN AU3 PK_WTPART 115741
10) TABLE ACCESS BY INDEX ROWID AU3 WTPARTMASTER 22 893 16074
9) INDEX RANGE SCAN AU3 WTPARTMASTER$WTPARTNUMBER 2 893
13) SORT JOIN 4785 783 10179
12) TABLE ACCESS FULL AU3 DQAMILESTONE 2 783 10179
22) FILTER
21) SORT GROUP BY NOSORT 4 1 26
20) NESTED LOOPS 4 3 78
17) TABLE ACCESS BY INDEX ROWID AU3 DQABASELINEMASTER 1 1 16
16) INDEX UNIQUE SCAN AU3 DQABASELINEMASTER$PROJECTID 1
19) TABLE ACCESS BY INDEX ROWID AU3 DQABASELINE 3 780 7800
18) INDEX RANGE SCAN AU3 DQABASELINE$UNIQUE0 2 780
这个整个的explain plan,能看出什么?
语句1 SELECT dname, deptno FROM dept WHERE deptno NOT IN (SELECT deptno FROM emp); 语句2 SELECT dname, deptno FROM dept WHERE NOT EXISTS (SELECT deptno FROM emp WHERE dept.deptno = emp.deptno); 明显的,2要比1的执行性能好很多 因为1中对emp进行了full table scan,这是很浪费时间的操作。而且1中没有用到emp的index, 因为没有where子句。而2中的语句对emp进行的是range scan。
select max(a.ida2a2) ida2a2 from au3.wtdocumentmaster f,
au3.dqabaselinemaster g, au3.dqabaseline a
where g.projectid = f.name
and a.ida3masterreference = g.ida2a2
group by a.ida3masterreference
相关表和索引最好作一下统计.