谢谢上面大哥!最后一句原来程序里是这样的( ( "CONTRACT"."TRADEMARK_ID" = :AA) or :AA=0 ) :AA是参数,当我要选者TRADEMARK_ID条件为所有时,我就定义:AA为0,这样这时这一条件就相当于没有。还有你说的计划怎么做!万分感谢!
原来的语句怎么看都觉得很复杂,可以考虑用下面这个替换,清晰一些:) SELECT a.ym, c.DAY, a.timeseg_id, b.contract_no, a.adcontent, b.trade_id, a.v_fileindex, d.channel_id, e.media_type_id FROM consch_list a, contract b, contract_schedule c, timesegment d, channel e WHERE a.contract_no = b.contract_no AND a.consch_id = c.consch_id AND a.timeseg_id = d.timeseg_id AND d.channel_id = e.channel_id AND e.media_type_id = 1 AND (b.trade_id = :AA OR :AA = 0);建议尽量给contract_no建立索引,另外最后一个条件改成 (:AA=0 or b.trade_id = :AA);试试看,理论上说,应该没有效果.
启动查询计划的步骤(不知道贴了多少次了...) 1. 用SYS用户登陆,执行下面的SQL语句,也可以用sqlplus调入. 文件路径: %ORACLE_HOME%\SQPLPLUS\admin\plustrce.sql 例如: C:\oracle\ora817\SQPLPLUS\admin\plustrce.sql 这个文件的内容和下面给出的是一样的. set echo on drop role plustrace; create role plustrace; grant select on v_$sesstat to plustrace; grant select on v_$statname to plustrace; grant select on v_$session to plustrace; grant plustrace to dba with admin option; (也可以不将角色赋给dba,赋给指定的用户)
set echo off 2. 以上面的用户名登陆, 运行下面的过程.也可以用sqlplus调入. 文件路径:%ORACLE_HOME%\RDBMS\admin\utlxplan.sql 例如: C:\oracle\ora817\RDBMS\admin\utlxplan.sql create table PLAN_TABLE ( statement_id varchar2(30), timestamp date, res varchar2(80), operation varchar2(30), options varchar2(30), object_node varchar2(128), object_owner varchar2(30), object_name varchar2(30), object_instance numeric, object_type varchar2(30), optimizer varchar2(255), search_columns number, id numeric, parent_id numeric, position numeric, cost numeric, cardinality numeric, bytes numeric, other_tag varchar2(255), partition_start varchar2(255), partition_stop varchar2(255), partition_id numeric, other long, distribution varchar2(30)); 3. 进入sqlplus,执行: set autotrace on 或者执行: set autotrace traceonly 4. 运行SQL语句,就可以看到具体的查询计划。根据查询计划 分析SQL语句的瓶颈.
把or 改成union看是不是快
在我的开发过程中也碰到过这种问题,主要原因是在联接上用了OR的话,就会出现效率其慢的结果: 如 select * from tba a inner join tbb b on a.line=b.line or a.line1=b.line2 就会很慢的了。我们都是用UNION ALL 的方法来解决的 select * from tba a inner join tbb b on a.line=b.line UNION ALL select * from tba a inner join tbb b on or a.line1=b.line2 这样可以大大提高你的执行效率。
:AA是参数,当我要选者TRADEMARK_ID条件为所有时,我就定义:AA为0,这样这时这一条件就相当于没有。还有你说的计划怎么做!万分感谢!
SELECT
a.ym, c.DAY, a.timeseg_id, b.contract_no, a.adcontent, b.trade_id,
a.v_fileindex, d.channel_id, e.media_type_id
FROM consch_list a,
contract b,
contract_schedule c,
timesegment d,
channel e
WHERE a.contract_no = b.contract_no
AND a.consch_id = c.consch_id
AND a.timeseg_id = d.timeseg_id
AND d.channel_id = e.channel_id
AND e.media_type_id = 1
AND (b.trade_id = :AA OR :AA = 0);建议尽量给contract_no建立索引,另外最后一个条件改成
(:AA=0 or b.trade_id = :AA);试试看,理论上说,应该没有效果.
这样一步一步的来做,就可以很清晰的看到哪里出了问题,而且也不麻烦。另外请教哪里有一些大型的数据库(如这样1000000行规模的)可以提供下载作为练习,不管是Oracle的还是SQL SERVER的。因为这些效率问题,只有在操作大的数据库中来会有体会。谢谢
启动查询计划的步骤(不知道贴了多少次了...) 1. 用SYS用户登陆,执行下面的SQL语句,也可以用sqlplus调入.
文件路径: %ORACLE_HOME%\SQPLPLUS\admin\plustrce.sql
例如: C:\oracle\ora817\SQPLPLUS\admin\plustrce.sql 这个文件的内容和下面给出的是一样的. set echo on
drop role plustrace;
create role plustrace; grant select on v_$sesstat to plustrace;
grant select on v_$statname to plustrace;
grant select on v_$session to plustrace;
grant plustrace to dba with admin option;
(也可以不将角色赋给dba,赋给指定的用户)
set echo off 2. 以上面的用户名登陆, 运行下面的过程.也可以用sqlplus调入.
文件路径:%ORACLE_HOME%\RDBMS\admin\utlxplan.sql
例如: C:\oracle\ora817\RDBMS\admin\utlxplan.sql create table PLAN_TABLE (
statement_id varchar2(30),
timestamp date,
res varchar2(80),
operation varchar2(30),
options varchar2(30),
object_node varchar2(128),
object_owner varchar2(30),
object_name varchar2(30),
object_instance numeric,
object_type varchar2(30),
optimizer varchar2(255),
search_columns number,
id numeric,
parent_id numeric,
position numeric,
cost numeric,
cardinality numeric,
bytes numeric,
other_tag varchar2(255),
partition_start varchar2(255),
partition_stop varchar2(255),
partition_id numeric,
other long,
distribution varchar2(30)); 3. 进入sqlplus,执行: set autotrace on 或者执行:
set autotrace traceonly 4. 运行SQL语句,就可以看到具体的查询计划。根据查询计划
分析SQL语句的瓶颈.
如
select * from tba a inner join tbb b on a.line=b.line or a.line1=b.line2 就会很慢的了。我们都是用UNION ALL 的方法来解决的
select * from tba a inner join tbb b on a.line=b.line
UNION ALL
select * from tba a inner join tbb b on or a.line1=b.line2
这样可以大大提高你的执行效率。