Oracle 存储过程更新表列的时间太长
我创建了一个Oracle 存储过程更新表列的时间太长,oracle,stored-procedures,update-statement,Oracle,Stored Procedures,Update Statement,我创建了一个存储过程,它花费了太多的时间来更新表的列。比如说3小时更新43k条记录中的2.5k条记录 因此,我可以减少更新记录的时间。下面是我的逻辑 程序更新\u MST\u信息\u BKC ( NVARCHAR2中的P_SAPID ) 作为 v_cityname varchar2(500):=''; v_neid varchar2(500):=''; 瓦查尔纬度2(500):=''; v_经度varchar2(500):=''; v_结构类型varchar2(500):=''; v_jc_n
存储过程
,它花费了太多的时间来更新表的列。比如说3小时更新43k条记录中的2.5k条记录
因此,我可以减少更新记录的时间。下面是我的逻辑
程序更新\u MST\u信息\u BKC
(
NVARCHAR2中的P_SAPID
)
作为
v_cityname varchar2(500):='';
v_neid varchar2(500):='';
瓦查尔纬度2(500):='';
v_经度varchar2(500):='';
v_结构类型varchar2(500):='';
v_jc_name varchar2(500):='';
v_jc_代码varchar2(500):='';
v_公司代码varchar2(500):='';
v_cnt编号:=0;
开始
从结构映射中选择count(*)到v_cnt,其中RJ_SAPID=P_SAPID,rownum=1;
如果v_cnt>0,则
开始
选择RJ_城市名称、RJ_网络实体ID、纬度、经度、RJ_结构类型、RJ_JC_名称、RJ_JC_代码、'6000'
从结构enodeb_映射中,RJ_SAPID=P_SAPID,rownum=1,转换为v_cityname、v_neid、v_纬度、v_经度、v_结构类型、v_jc_名称、v_jc_代码、v_公司代码;
更新tbl_ipcolo_mast_信息集
城市名称=城市名称,
NEID=v_NEID,
设施纬度=垂直纬度,
设施经度=v经度,
RJ_结构类型=v_结构类型,
RJ_JC_NAME=v_JC_NAME,
RJ_JC_代码=v_JC_代码,
公司代码=v公司代码
其中SAP_ID=P_SAPID;
结束;
如果结束;
结束更新\u MST\u信息\u BKC代码>3小时?那太过分了。sap\u id
列是否索引?即使不是这样,43K行的数据集也太小了
这个过程叫什么?它是另一个代码的一部分吗?也许是某个不幸的循环
,它一行一行地做一些事情(这反过来又是慢慢来的)
一些反对意见:
- 所有这些变量的数据类型真的是
varchar2(500)
?考虑声明它们,使它们接受表列的数据类型,例如“代码> VyCyNyMeNealthyEnEdBeDeMatr.RjyCITYYNAME%类型;<代码>。此外,没有必要明确地说它们的值为null(:=''
),默认情况下是这样的
select
语句,该语句检查表中是否有该参数值的内容应重写为使用EXISTS
,因为它的性能应优于您使用的rownum=1
条件。
<>也请考虑使用异常处理程序(<代码>未发现数据< /代码>如果某个ID没有行;<代码>太多行< /代码>如果有两行或更多行)
select
将数据收集到变量中的语句具有相同的条件;您真的希望每个ID(作为参数传递)都不止一行吗
无论如何,整个过程的代码可以缩短为一个update
语句:
update tbl_ipcolo_mst_info t set
(t.city_name, t.neid, ...) = (select s.rj_city_name,
s.rj_network_entity_id, ...
from structure_enodeb_mapping s
where s.rj_sapid = t.sap_id
)
where t.sap_id = p_sapid;
如果有需要更新的内容,它将被更新。如果没有匹配的t.sap\u id
,什么也不会发生。据我所知,它正在更新TBL\u IPCOLO\u MAST\u INFO
具有sap\u id=p\u SAPID
意味着它正在更新一条记录,并且您必须为每条记录调用过程
一次调用过程并一次更新所有记录是一种很好的做法。(在您的情况下,2.5k记录只能在本程序的一次调用中更新)
根据您的要求,目前,我已经更新了过程代码,使其仅执行MERGE语句,这与您问题中针对单个p\u SAPID
的多个sql相同
PROCEDURE UPDATE_MST_INFO_BKC (
P_SAPID IN NVARCHAR2
) AS
BEGIN
MERGE INTO TBL_IPCOLO_MAST_INFO I
USING (
SELECT
RJ_CITY_NAME,
RJ_NETWORK_ENTITY_ID,
LATITUDE,
LONGITUDE,
RJ_STRUCTURE_TYPE,
RJ_JC_NAME,
RJ_JC_CODE,
'6000' AS COMPANY_CODE,
RJ_SAPID
FROM
STRUCTURE_ENODEB_MAPPING
WHERE
RJ_SAPID = P_SAPID
AND ROWNUM = 1
)
O ON ( I.SAP_ID = O.RJ_SAPID )
WHEN MATCHED THEN
UPDATE SET I.CITY_NAME = O.RJ_CITY_NAME,
I.NEID = O.RJ_NETWORK_ENTITY_ID,
I.FACILITY_LATITUDE = O.LATITUDE,
I.FACILITY_LONGITUDE = O.LONGITUDE,
I.RJ_STRUCTURE_TYPE = O.RJ_STRUCTURE_TYPE,
I.RJ_JC_NAME = O.RJ_JC_NAME,
I.RJ_JC_CODE = O.RJ_JC_CODE,
I.COMPANY_CODE = O.COMPANY_CODE;
END UPDATE_MST_INFO_BKC;
干杯 谢谢你这么快的回复。是的,我正在按照你提到的一行一行地更新。我可以试试你的简短回答并核对一下吗?不客气。试试看,看看会发生什么。如果没有按预期工作,请不要提交!没什么大不了的;修复了无效格式,因为纯文本格式为代码。错误(1102,23):PL/SQL:ORA-00904:“O”。“RJ_SAPID”:无效标识符
有错误ohh,是。。。我现在已经更新了答案!!请检查它将使用STRUCTURE\u ENODEB\u MAPPING
中的值更新表TBL\u IPCOLO\u MAST\u INFO
,条件是I.SAP\u ID=O.RJ\u SAPID
您能告诉我您是如何使用此过程吗?我正在使用此过程根据我的代码