Re: [oracle_br] BULK COLLECT LIMIT

2008-12-12 Por tôpico Carlos E. Gorges
Boa tarde,

A hint APPEND só é utilizada em insert-selects ou merge. No caso
apresentado ela é IGNORADA.
Note que mesmo nos casos aplicáveis, a hint APPEND, por forçar
sincronia do retorno para o usuário após a gravação direta no
datafile, pode deixar a carga mais lenta. Fora que a tabela é locada
integralmente (TM lock) e requer commit a cada DML, como em uma
gravação paralela.

Para melhorar a performance nesse caso você terá que fazer bulk load
com a sintaxe forall insert, permitindo o uso completo ou perto disso
do(s) bloco(s) trabalhado(s) (current mode), ao invés da abordagem
padrão linha<->bloco(s) ... olhe exemplos em:
http://www.psoug.org/reference/array_processing.html.

Muito cuidado com NOLOGGING, em caso de crash os blocos alterados que
ainda não foram descarregados para os datafiles em um checkpoint
(estão como dirt no buffer cache) serão perdidos, e caso essa tabela
tenha índices, a estrutura dos índices ficarão inconsistentes à
tabela. Minha dica é manter a tabela em LOGGING e somente nas cargas
use a hint NOLOGGING, forçando um checkpoint no termino (alter system
checkpoint) ... note que a hint NOLOGGING só existe após o oracle 9.

cya[];
Carlos E. Gorges 

2008/12/12 Thiago Delfim :
> Pessoal,
> Tenho um processo de carga em que fazemos uma consulta que retorna
> aproximadamente 14 milhões de linhas que são inseridas em uma única tabela.
> Atualmente fazemos os inserts com BULK COLLECT LIMIT 1000.
>
> A rotina é mais ou menos assim:
>
> BEGIN
> OPEN cur;
> LOOP
> BEGIN
> FETCH cur BULK COLLECT INTO cvar1,
> cvar2,
> cvar3
> LIMIT 1000;
> IF (cvar1.COUNT > 0) THEN
> FOR i IN 1..cvar1.COUNT
> LOOP
> BEGIN
> INSERT /*+ APPEND */
> INTO TABELA(var1,
> var2,
> var3)
> VALUES (cvar1(i),
> cvar2(i),
> cvar3(i));
>
> Eu acredito que nesse caso (em que é feito INSERT APPEND, a tabela é
> NOLOGGING e não há nenhum tratamento dessas informações no LOOP), poderia
> ser utilizado um FORALL ou mesmo FETCH cur INTO tabela diretamente.
>
> Vocês acham que haveria ganho de performance em usar uma forma diferente?


[oracle_br] BULK COLLECT LIMIT

2008-12-12 Por tôpico Thiago Delfim
Pessoal,
Tenho um processo de carga em que fazemos uma consulta que retorna
aproximadamente 14 milhões de linhas que são inseridas em uma única tabela.
Atualmente fazemos os inserts com BULK COLLECT LIMIT 1000.

A rotina é mais ou menos assim:

BEGIN
  OPEN cur;
  LOOP
BEGIN
  FETCH cur BULK COLLECT INTO cvar1,
  cvar2,
  cvar3
  LIMIT 1000;
  IF (cvar1.COUNT > 0) THEN
FOR i IN 1..cvar1.COUNT
LOOP
  BEGIN
INSERT /*+ APPEND */
INTO   TABELA(var1,
  var2,
  var3)
VALUES (cvar1(i),
cvar2(i),
cvar3(i));

Eu acredito que nesse caso (em que é feito INSERT APPEND, a tabela é
NOLOGGING e não há nenhum tratamento dessas informações no LOOP), poderia
ser utilizado um FORALL ou mesmo FETCH cur INTO tabela diretamente.

Vocês acham que haveria ganho de performance em usar uma forma diferente?



-- 
Thiago Delfim
Oracle & SQL Server Database Administrator
Oracle 9i Database Certified Associate
tdel...@gmail.com (MSN)
Campinas/SP
(19) 8204-2681 / 9111-1439
Robert Orben  - "Older people shouldn't eat health food, they need all the
preservatives they can get."


[As partes desta mensagem que não continham texto foram removidas]