频繁的调用select大表的Function,比起直接包在sql中select,效能怎么
频繁的调用select大表的Function,比起直接包在sql中select,效能如何?
为了判断select的记录是否符合要求,会在select的时候传入参数返回一个flag,判断是否是合法的
function的内容如下
调用的SQL
Function中用到的表记录大概两万多,且都是主键扫描。
不晓得在频繁的调用function的时候,频繁的select操作是否影响性能,比起直接在sql中直接加语句中加条件判断,如下:
哪种方法效率更高?为什么?
若是function中调用的表记录数是亿级别的,是否应避免这样使用?
------解决方案--------------------
首先:你的函数写的有毛病,排序是没有必要加的
原因:你的目的无非是想看asc排序之后有没有第一条记录,有就是Y 没有就是N,我实在想不出 排序 和 不排序 对结果有什么影响,况且排序是很费“体力”的事情。
其次:where条件中用到not 往往都是很费力的事情,因为需要全表扫描才能知道到底是不是真正的 not,这很好理解,因为只要有一条记录扫描不到,那么就有可能存在 非 not 的情况。
至于具体执行效率,还要关注执行计划,做具体分析。
不过根据你的业务逻辑从直观上讲,个人比较倾向于:第一种fuction的方式。
------解决方案--------------------
效率基本没差别。
2w条的记录对数据库是小case了。
order by和rownum也没什么问题。
------解决方案--------------------
如果你是联机应用,一次只判断很少(相对于表中总数据而言)记录的状态,用你原来的方法基本正确.另外把二楼的第一条建议用上.
如果你是批量任务,要判断ZZ_WHITEPMSTORAGE_SUMMARY Z中多数记录的状态,建议你用语句的方式,能减少sql引起于plsql引擎之间切换,而且func中外部语句执行计划不能连接优化.
用not 效率比较低,可以换成关联(你可以用left jion)
SELECT decode(nvl(H.LOT_2,0),0,'N','Y') flag
示例
FROM ZZ_WHITEPMSTORAGE_SUMMARY Z,
ZZ_CANCEL_OPERATION_SUMMARY H
WHERE Z.LOT2 =H.LOT_2(+)
AND Z.CREATE_DATE < H.CREATE_DATE(+)
AND H.APPLICATION_NAME(+) = 'PartCutRetreatWorkData'
最后如果你的数据只有千八百地,就不要纠结方法了,差别不大.
------解决方案--------------------
为了判断select的记录是否符合要求,会在select的时候传入参数返回一个flag,判断是否是合法的
function的内容如下
- SQL code
CREATE OR REPLACE FUNCTION FN_CANCEL_WHITE(BarCode IN VARCHAR2, CREATEDATE IN DATE) RETURN VARCHAR2 IS ABEXISTS VARCHAR2(2); BEGIN SELECT CASE WHEN COUNT(LOT_2) = 0 THEN 'N' ELSE 'Y' END INTO ABEXISTS FROM (SELECT H.LOT_2 FROM ZZ_CANCEL_OPERATION_SUMMARY H WHERE H.LOT_2=BarCode AND H.CREATE_DATE > CREATEDATE AND H.APPLICATION_NAME = 'PartCutRetreatWorkData' ORDER BY CREATE_DATE ASC) WHERE ROWNUM = 1; RETURN ABEXISTS; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN 0; END;
调用的SQL
- SQL code
SELECT fn_cancel_white(Z.LOT2,Z.CREATE_DATE) FLAG FROM ZZ_WHITEPMSTORAGE_SUMMARY Z
Function中用到的表记录大概两万多,且都是主键扫描。
不晓得在频繁的调用function的时候,频繁的select操作是否影响性能,比起直接在sql中直接加语句中加条件判断,如下:
- SQL code
WHERE NOT EXISTS (SELECT * FROM ZZ_CANCEL_OPERATION_SUMMARY H WHERE H.LOT_2= Z.LOT2 AND H.CREATE_DATE > Z.CREATE_DATE AND H.APPLICATION_NAME = 'PartCutRetreatWorkData')
哪种方法效率更高?为什么?
若是function中调用的表记录数是亿级别的,是否应避免这样使用?
------解决方案--------------------
首先:你的函数写的有毛病,排序是没有必要加的
原因:你的目的无非是想看asc排序之后有没有第一条记录,有就是Y 没有就是N,我实在想不出 排序 和 不排序 对结果有什么影响,况且排序是很费“体力”的事情。
其次:where条件中用到not 往往都是很费力的事情,因为需要全表扫描才能知道到底是不是真正的 not,这很好理解,因为只要有一条记录扫描不到,那么就有可能存在 非 not 的情况。
至于具体执行效率,还要关注执行计划,做具体分析。
不过根据你的业务逻辑从直观上讲,个人比较倾向于:第一种fuction的方式。
------解决方案--------------------
效率基本没差别。
2w条的记录对数据库是小case了。
order by和rownum也没什么问题。
------解决方案--------------------
如果你是联机应用,一次只判断很少(相对于表中总数据而言)记录的状态,用你原来的方法基本正确.另外把二楼的第一条建议用上.
如果你是批量任务,要判断ZZ_WHITEPMSTORAGE_SUMMARY Z中多数记录的状态,建议你用语句的方式,能减少sql引起于plsql引擎之间切换,而且func中外部语句执行计划不能连接优化.
用not 效率比较低,可以换成关联(你可以用left jion)
SELECT decode(nvl(H.LOT_2,0),0,'N','Y') flag
示例
FROM ZZ_WHITEPMSTORAGE_SUMMARY Z,
ZZ_CANCEL_OPERATION_SUMMARY H
WHERE Z.LOT2 =H.LOT_2(+)
AND Z.CREATE_DATE < H.CREATE_DATE(+)
AND H.APPLICATION_NAME(+) = 'PartCutRetreatWorkData'
最后如果你的数据只有千八百地,就不要纠结方法了,差别不大.
------解决方案--------------------