1

我创建了一个存储过程,它花费了太多时间来更新表的列。假设 3 小时更新 43k 条记录中的 2.5k 条记录。

那么我可以减少更新记录的时间吗?以下是我的相同逻辑。

procedure UPDATE_MST_INFO_BKC
  (
    P_SAPID IN NVARCHAR2
  )
  as
  v_cityname varchar2(500):='';
  v_neid varchar2(500):='';
  v_latitude varchar2(500):='';
  v_longitude varchar2(500):='';
  v_structuretype varchar2(500):='';
  v_jc_name varchar2(500):='';
  v_jc_code varchar2(500):='';
  v_company_code varchar2(500):='';
  v_cnt number :=0;
  
  begin
  select count(*) into v_cnt from structure_enodeb_mapping where  RJ_SAPID=P_SAPID  and rownum=1;
  
  if v_cnt > 0 then 
  begin
  
   select RJ_CITY_NAME, RJ_NETWORK_ENTITY_ID,LATITUDE,LONGITUDE,RJ_STRUCTURE_TYPE,RJ_JC_NAME,RJ_JC_CODE,'6000' 
   into v_cityname,v_neid,v_latitude, v_longitude, v_structuretype,v_jc_name,v_jc_code,v_company_code from structure_enodeb_mapping where RJ_SAPID=P_SAPID  and rownum=1;

        update tbl_ipcolo_mast_info set 
        
        CITY_NAME                   = v_cityname,
        NEID                        = v_neid,
        FACILITY_LATITUDE           = v_latitude,
        FACILITY_LONGITUDE          = v_longitude,
        RJ_STRUCTURE_TYPE           = v_structuretype,
        RJ_JC_NAME                  = v_jc_name,  
        RJ_JC_CODE                  = v_jc_code,  
        COMPANY_CODE                = v_company_code
        where SAP_ID=P_SAPID;
  
  end;
  end if;   

  end UPDATE_MST_INFO_BKC;

我可以对此进行哪些调整?

4

2 回答 2

1

3小时?这太过分了。列是否sap_id被索引?即使不是,43K 行的数据集也太小了。

你怎么称呼这个程序?它是否是另一个代码的一部分,也许是一些不幸的代码,loop它逐行执行(这反过来又是缓慢的)?

一些反对意见:

  • 所有这些变量的数据类型都是真的varchar2(500)吗?考虑声明它们,以便它们采用表列的数据类型,例如v_cityname structure_enodeb_mapping.rj_city_name%type;. 此外,没有必要明确说它们的值为 null ( := ''),默认情况下是这样的
  • select检查表中是否有该参数值的某些内容的语句应该被重写以使用,因为它应该比您使用的条件 EXISTS执行得更好。rownum = 1
    • 另外,考虑使用异常处理程序(no-data-found如果某个 ID 没有行;too-many-rows如果有两行或多行)
  • 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_id,什么都不会发生。

于 2019-08-14T06:08:37.897 回答
1

据我了解您的代码,它正在更新TBL_IPCOLO_MAST_INFO意味着SAP_ID = P_SAPID它正在更新一条记录,您必须为每条记录调用该过程。

一次调用该过程并一次更新所有记录是一种很好的做法。(在您的情况下,必须仅在此过程的一次调用中更新 2.5k 条记录)

根据您的要求,目前,我已将过程代码更新为仅执行 MERGE 语句,这与您的问题中的多个 SQL 相同P_SAPID

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;

干杯!!

于 2019-08-14T06:12:17.237 回答