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 BKC3小时?那太过分了。
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
您能告诉我您是如何使用此过程吗?我正在使用此过程根据我的代码