有没有办法优化这个查询?

Posted

技术标签:

【中文标题】有没有办法优化这个查询?【英文标题】:Is there a way to optimize this query? 【发布时间】:2017-07-19 14:13:11 【问题描述】:
declare
  n_docid number;
  n_orgid number;
  n_docstateid number;
  n_docstateversion number;
  n_doctypeid number;
  n_count number;
begin
  for I in (select DOCID from DC_EXP_BO where INF_DATEDOCUMENT > '01.01.17' and 
INF_DATEDOCUMENT < '31.12.17')
loop
begin
  select DOCID, DOCSTATEID, DOCTYPEID, DOCSTATE_VERSION into 
  n_docid, n_docstateid, n_doctypeid, n_docstateversion from DOC 
  where DOCID = I.DOCID;

  select ORGID into n_orgid from ORG
  where systemname = (select distinct RB_CODEGRBS from DC_EXP_BO where DOCID = n_docid);


  select count(*) into n_count from ROUTECONTEXT
  where DOCID = n_docid and ORGID = n_orgid;

  if (n_count = 0) then
  insert into ROUTECONTEXT 
    (ROUTECONTEXTID, VERSION, DOCID, LOCALDOCSTATEID, OWNERID, LASTPRINTDATE, PRINTED, RECEIVED, ORGID, ARCHIVE, EXPORTSTATUS, DOCTYPEID, DOCSTATEID, DOCSTATE_VERSION, DELETED)
  values 
    (sq_routeContext.NEXTVAL, 0, n_docid, n_docstateid, null, null, 0, 0, n_orgid, 0, 'NOT_EXPORTED', n_doctypeid, n_docstateid, n_docstateversion, 0);
  end if;
exception
  when no_data_found then
continue;
end;
end loop;
end;
/

我们为生产编写了数据修复。还有一个问题。 For 语句 select 可以返回大约 100 万个 ID。是否有可能以某种方式优化此查询?

【问题讨论】:

【参考方案1】:

您可以进行的最有效的优化是用一个基于集合的操作替换循环中的逐行插入和查找:

insert into ROUTECONTEXT 
    (ROUTECONTEXTID, VERSION, DOCID, LOCALDOCSTATEID, OWNERID, LASTPRINTDATE, PRINTED, RECEIVED, ORGID, ARCHIVE, EXPORTSTATUS, DOCTYPEID, DOCSTATEID, DOCSTATE_VERSION, DELETED)
select sq_routeContext.NEXTVAL, 
          0, 
          DOC.DOCID, 
          DOC.DOCSTATEID, 
          null,
          null,
          0,
          0,
          org.ORGID,
          0,
          'NOT_EXPORTED',
          DOC.DOCSTATEID, 
          DOC.DOCTYPEID, 
          DOC.DOCSTATE_VERSION ,
          0
from DC_EXP_BO
    join doc
        on DC_EXP_BO.DOCID = DOC.DOCID 
    join org 
        on org.systemname =  DC_EXP_BO.RB_CODEGRBS 
where DC_EXP_BO.INF_DATEDOCUMENT > date '2017.01.01'
and DC_EXP_BO.INF_DATEDOCUMENT < date '2017.12.31' 
and not exists ( select null 
                 from ROUTECONTEXT
                 where ROUTECONTEXT.DOCID = doc.docid 
                 and ROUTECONTEXT.ORGID = org.orgid 
               )
/

假设 DC_EXP_BO.INF_DATEDOCUMENT 是 DATE 数据类型,使用正确的日期语义可能更具执行性,并且肯定会更安全。但它是一个字符串,用您在问题中发布的内容替换 WHERE 子句的那部分。

【讨论】:

成功了!我不能给你的业力加+,因为没有足够的声望。 您提出了问题,您可以对自己的问题进行投票并接受答案。

以上是关于有没有办法优化这个查询?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法优化这个mysql查询?

条件检查之间的Mysql中有多个条件?有没有办法优化这个查询?

有没有办法提高这个简单的 WordPress 数据库查询的性能?

有没有办法组合 mysqli 查询或给它们一个优化序列?

如何优化这个 sql 查询(内连接)

我的Myqls数据库中有2个数据表,每个数据表都有超过3千万条记录,查询效率很低,有没有什麽好的办法优化?