表结构是这样的
create table TableA
(
SERIALNO VARCHAR2(32) not null,
OBJECTNO VARCHAR2(32) not null,
RESULT1 VARCHAR2(18),
RESULT2 VARCHAR2(18),
RESULT3 VARCHAR2(18),
INPUTORGID VARCHAR2(20),
INPUTUSERID VARCHAR2(20),
INPUTDATE VARCHAR2(10),
FINALLYRESULT VARCHAR2(18),
DATE VARCHAR2(10) not null
)
create or replace function getRealResult(pNO varchar2,pDate varchar2)
/***********************************************************************
* Purpose: 得到近期最新结果
* Parameter:pNO
* pate 格式YYYY/MM/DD
***********************************************************************/
return varchar2
is
sResult varchar2(20);
begin
select result into sResult from (
Select result From (
select accountDATE,nvl(FinallyResult,nvl(Result3,nvl(Result2,nvl(Result1,'X')))) result
from TableA
where accountDATE<=pDate and objectNO=pNO
) Where result<>'X'
order by accountDATE desc
) where RowNum=1;
return sResult;
EXCEPTION
WHEN NO_DATA_FOUND THEN
return '01';
WHEN OTHERS THEN
return '01';
end;执行里面的sql时 执行计划看着是挺快的
但是带入到查询的sql语句里 查询就慢了 用这个函数 和不用这个函数 速度就完全不一样
不知道什么原因 索引也都用上了求高人解答
create table TableA
(
SERIALNO VARCHAR2(32) not null,
OBJECTNO VARCHAR2(32) not null,
RESULT1 VARCHAR2(18),
RESULT2 VARCHAR2(18),
RESULT3 VARCHAR2(18),
INPUTORGID VARCHAR2(20),
INPUTUSERID VARCHAR2(20),
INPUTDATE VARCHAR2(10),
FINALLYRESULT VARCHAR2(18),
DATE VARCHAR2(10) not null
)
create or replace function getRealResult(pNO varchar2,pDate varchar2)
/***********************************************************************
* Purpose: 得到近期最新结果
* Parameter:pNO
* pate 格式YYYY/MM/DD
***********************************************************************/
return varchar2
is
sResult varchar2(20);
begin
select result into sResult from (
Select result From (
select accountDATE,nvl(FinallyResult,nvl(Result3,nvl(Result2,nvl(Result1,'X')))) result
from TableA
where accountDATE<=pDate and objectNO=pNO
) Where result<>'X'
order by accountDATE desc
) where RowNum=1;
return sResult;
EXCEPTION
WHEN NO_DATA_FOUND THEN
return '01';
WHEN OTHERS THEN
return '01';
end;执行里面的sql时 执行计划看着是挺快的
但是带入到查询的sql语句里 查询就慢了 用这个函数 和不用这个函数 速度就完全不一样
不知道什么原因 索引也都用上了求高人解答
建议换成这样的排序方式。 用分析函数来做。
/***********************************************************************
* Purpose: 得到近期最新结果
* Parameter:pNO
* pate 格式YYYY/MM/DD
***********************************************************************/
return varchar2 is
sResult varchar2(20);
begin
select result
into sResult
from (Select result,
row_number() over(order by accountDATE desc) rn--排序记录标号。
From (select accountDATE,
nvl(FinallyResult,
nvl(Result3, nvl(Result2, nvl(Result1, 'X')))) result
from TableA
where accountDATE <= pDate
and objectNO = pNO)
Where result <> 'X'
/*order by accountDATE desc*/)
where rn = 1;
return sResult;
EXCEPTION
WHEN NO_DATA_FOUND THEN
return '01';
WHEN OTHERS THEN
return '01';
end;
1,order by order by accountDATE desc是全表排序扫描之后取前N条,一定走的是table span
2,row_number() over(order by accountDATE desc) 走的是索引扫描,只排出前N条,而且只取前N条记录。
ORDER BY 字段是和你索引有关的,如果排序字段本身有索引那是很快,本身没有就很慢的
分析函数并不是肯定走索引扫描的,ORDER 也不是肯定走全表的
并且 ROW_NUMBER这个分析函数并没有只排出前N条,而且只取前N条的记录这个说法
你这张表的数据量是多少?
你的查询语句是怎么样的?
用to_date函数格式化成你入库的格式,试下。希望能对你有帮助
( pNO VARCHAR2,
pDate VARCHAR2)
/***********************************************************************
* Purpose: 得到近期最新结果
* Parameter:pNO
* pate 格式YYYY/MM/DD
***********************************************************************/
RETURN VARCHAR2
IS
w_max_accountDate VARCHAR2(64);
sResult VARCHAR2(20);
BEGIN
SELECT MAX(accountdate)
INTO w_max_accountdate
FROM tablea
WHERE accountDATE <=pDate
AND objectNO =pNO
AND finallyresult IS NOT NULL
AND result3 IS NOT NULL
AND result2 IS NOT NULL
AND result1 IS NOT NULL;
SELECT NVL(FinallyResult,NVL(Result3,NVL(Result2,NVL(Result1,'X'))))
INTO sResult
FROM tablea
WHERE accountDATE = w_max_accountdate
AND objectNO = pNO
AND finallyresult IS NOT NULL
AND result3 IS NOT NULL
AND result2 IS NOT NULL
AND result1 IS NOT NULL
AND rownum =1;
RETURN sResult;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN '01';
WHEN OTHERS THEN
RETURN '01';
END;
/
create table tableb
(objectNo varchar2(32)
, col2
, col3
, ...);现在你做类似于如下的查询
select objectNo, getRealResult(objectNo, to_char(sysdate, 'yyyy/mm/dd')
from tableb;那对于每个objectNo,oracle都必须对tableA进行大量扫描,效率当然很差。这种情况下不要用函数,直接做联合查询,那就只需要对tableA做一次扫描。