Oracle 循环连接语句

Oracle Loop Through Join Statement

我需要在 PL-SQL 中执行一条语句,即选择 ID,针对这些 ID 的子集执行连接...在下面的示例中,我有大约 700000 个客户,和一个 far 比在这个例子中的简单 while 循环中显示的更复杂的查询......我的播种性能很差并且很好奇是否切断我当前的 PL-SQL 到 'chunks' 会产生性能提升吗?

目前:

declare
  TYPE customerIdTabType IS TABLE OF customer.CustomerId%TYPE INDEX BY BINARY_INTEGER;
  vars customerIdTabType;

  -- maybe this should be in a table?
  cursor c is
  select
      c.CustomerId
  from customer c
  join productcustomers pc on pc.customerid = c.customerid
  join product p on p.productid = pc.productid
  where
      c.CustomerId > 1000;

begin  
  open c;
  loop
  fetch c bulk collect into vars limit 1000;

  -- here is where instead of looping through each item in vars
  -- i actually want to 'join' to the 1000 that i have.  
  forall i in 1..vars.count
  insert into xxx (CustomerId) 
  values (vars(i));
  commit;

  exit when vars.count = 0;
  end loop;
  close c;

end;
  1. Select 将 CustomerId 列表放入 "temporary" 存储容器 - 不确定选项是什么?
  2. 通过将这些 CustomerId 加入另一个查询来分批处理这些 CustomerIds...1000
  3. 将所有结果插入物理 table

所以,在 T-SQL 中可能是..

-- create a temp table
create table #MyTempTable (
    id int identity(1,1)
    ,customerid varchar(10)
)

-- populate that table
insert into #MyTempTable
select Customerid 
from schema.Customers

-- create some vars for looping
declare i int, c int;
select i = 0;
select c = count(*) from #MyTempTable;

-- loop through the original set in 'chunks' of 1000​
while i < c
begin
    insert into SomeOtherTable
        (CustomerId, CustomerAttribute)
    select
        o.CustomerId
        ,o.CustomerAttribute
    from OtherTable o
    join #MyTempTable t
    on o.CustomerId = t.CustomerId
    where
        t.Id between i and i+1000    -- from 0 to 1000

    set @i = i+1000    ​-- next loop will be from 1000 to 2000
end

谢谢

游标和临时 tables 在这里都是糟糕的解决方案。但是游标是两者中最糟糕的。 CTE(Common Table Expression)将是更好的解决方案,但在这里也没有必要。为什么不直接使用 insert into... select get-go

语句
Insert into xxx (CustomerId)
select
    c.CustomerId
from customer c
     join productcustomers pc on pc.customerid = c.customerid
     join product p on p.productid = pc.productid
where
    c.CustomerId > 1000;

如果确实需要拆分,请不要使用游标或临时文件 table。我希望 CTE 会是更好的解决方案。

那这个呢

select startid = min(id) from customer;
select maxid = max(id) from customer;

i = startid
while i <= maxid

begin
   with myCTE as (select ... from customer where id >= i and id < i + 1000)
   insert into xxx (....)
   select ....
   from myCustomerChunk
        join productcustomers pc on ....
        join product p on ....

   i = i+1000
end

这避免了在一个语句中执行所有 700000 次插入,这可能会降低您的查询...并且游标使事情变得更糟。 PS: 这是伪代码和实际代码的大杂烩,所以你必须弄清楚真正的语法。