大神帮忙看下,这边有两段代码都是用游标取数据,第二个代码里面游标的sql里面带有参数。
a表两千万数据 b表两百万数据
游标sql取出来的数据只有两条,用sqlplus直接执行只需要10s。
现在遇到个问题,第一个代码10s可以执行完,但是第二个sql要半小时...
有没有大神可以帮忙解答下为什么??????????
因为这个sql必须要带参数,急急急
DECLARE
CURSOR cur_query is
select a.name from t_name a, t_dep b
where a.id = b.id
and a.name like '%hj%';
rec_query cur_query%ROWTYPE;
BEGIN
open cur_query;
loop
FETCH cur_query INTO rec_query.name;
exit when cur_query%NOTFOUND;
END LOOP;
close cur_query;
END;
/
---------------------------------------------------------------------------------
DECLARE
v_name varchar2(10) := 'hj';
CURSOR cur_query is
select a.name from t_name a, t_dep b
where a.id = b.id
and a.name like '%' || hj || '%';
rec_query cur_query%ROWTYPE;
BEGIN
open cur_query;
loop
FETCH cur_query INTO rec_query.name;
exit when cur_query%NOTFOUND;
END LOOP;
close cur_query;
END;
/
------解决方案--------------------
v_name varchar2(10) := 'hj';
CURSOR cur_query is
select a.name from t_name a, t_dep b
where a.id = b.id
AND regexp_like(a.name,'*hj*')
rec_query cur_query%ROWTYPE;
用正则试试
------解决方案--------------------
CURSOR cur_query is
select a.name from t_name a, t_dep b
where a.id = b.id
AND regexp_like(a.name,'*'
------解决方案--------------------
v_name
------解决方案--------------------
'*')
rec_query cur_query%ROWTYPE;
这样写
------解决方案--------------------
用绑定变量试试
------解决方案--------------------
在pl/sql代码中,sql语句里涉及的变量会自动绑定,如果说,第二个语句和第一个的区别只是将hj换成变量来,这里上下来看执行计划应该不会有区别。
问题是第二个语句用的变量是hj,上面并没有定义这个变量,应该会报错的。是手误呢,还是说执行的语句不是这样的?
------解决方案--------------------
楼上说的不错,这两个语句其实执行计划不应该有啥区别,当然在变量一样的时候。
唯一值得确认的是楼主变量绑定的时候和第一条数据量不会不一样吧、
------解决方案--------------------
可能是变量的问题。可以在v$sql_plan中查看两条语句的执行计划有何不同
数据量大的情况下like '%xx%'的写法效率很差
在这个场景里,如果是因为变量的原因,想让SQL语句像第一条那样执行,试试这么写
DECLARE
v_name varchar2(10) := 'hj';
cur_query sys_refcursor;
type rec is record(name varchar2(1000));
rec_query rec;
BEGIN
open cur_query for 'select a.name from t_name a, t_dep b '
------解决方案--------------------
'where a.id = b.id '
------解决方案--------------------
'and a.name like ''%'
------解决方案--------------------
v_name
------解决方案--------------------
'%''';
loop
FETCH cur_query INTO rec_query.name;
exit when cur_query%NOTFOUND;
END LOOP;
close cur_query;
END;
/