Bom, faz tempo que "milhões de registros" deixou de ser algo extremo am hardware de produção, enterprise-class, mas de qquer maneira, eu penso nas coisas de sempre, ie : a) SE o teu servidor tiver capacidade sobrando (ie, memória, banda de I/O, CPU, etc) ainda não usada e disponível, vc pode fazer a query em paralelo : isso implica que "sessões escravas" serão abertas e alocadas ao mesmo tempo, cada uma lendo um pedacinho da "tabelona" .... Veja a Documentação do RDBMS (especialmente o manual de Concepts e o DW Guide da tua versão) para conceitos, sintaxes e alguns exemplos, e sites de referência como http://oracledoug.com/px.html e https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:39946845137685 para mais detalhes... Só REPITO : vc só pode pensar nisso ** SE ** realmente vc tem a capacidade sobrando no servidor : caso hoje ele já esteja no gargalo, Muito Provavelmente não vai haver capacidade de I/O, poder de CPU e memória livre para fazer frente à n sessões escravas "atacando" ao mesmo tempo... b) se assegurar que o sistema operacional e o I/O está setado para a melhor performance possível : por exemplo, é CRÍTICO que o ambiente permita I/O Asíncrono (Asynchronous I/O) e (via de regra) Direct I/O : Asynch significa que haverá múltiplos I/Os simultânoes, ie , os próximos I/Os que sejam independentes daquele em execução no momento NÃO PRECISAM ficar esperando que o atual termine... Isso é IMPRESCINDÍVEL em operações de full table scan que seja usado paralelismo, ajuda em muito via de regra paraque as sessões escravas não fiquem esperando umas pelas outras... Já o Direct I/O significa que os dados lidos são enviados diretamente para o RDBMS, que já tem buffers e caches Próprios, não se perdendo tempo em se fazer o Sistema Operacional copiar o que foi lido para os buffers/caches de sistema operacional.... Via de regra esse setting é Positivo para a performance... alguns ajustes do sub-sistema de I/O (como striping size, balanceamento de discos, etc) podem também influenciar se vc está usando um storage de discos : isso é algo a se alinhar com os sysadmins e time de storage c) não com se assegurar que o armazenamento interno está OK, e que as configs de DB estão apropriadas : por exemplo, o RDBMS ao fazer um full-table scan lê uma porção de blocos contíguos, o chamado EXTENT : se a tabela tiver sido criada com extents muito pequenos/consistentemente menores do que o máximo de bytes que o sistema operacional pode ler, OU se o tamanho do extent não for um múltiplo exato do tamanho máximo de I/O do sistema operacional, ao invés de um I/O serão necessários dois para ler o mesmo extent.... Outros pontos, ainda dentro do database : - pode valer a pena (via ALTER SESSION) setar temporariamente o parâmetro DB_FILE_MULTIBLOCK_READ_COUNT para um número de blocos que se equipare ao máximo I/O do sistema operacional - vc ** TEM ** que garantir que os dados da tal tabela estão gravados em extents com o ** mínimo possível ** de espaço em branco e/ou blocos alocados mas não usados - o objetivo aqui é, mais uma vez, diminuir ao máximo a qtdade de blocos (e portanto a qtdade de I/Os) necessária para se recuperar a informação... E que fique claro : blocos com espaço em branco e/ou não usados podem resultar tanto das opções de controle de armazenamento da tabela (exemplo, o porcentual de espaço que o RDBMS reserva para futuros UPDATEs) quanto de DMLs , como DELETEs que removeram os dados mas o espaço não foi reusado, ou de operações de APPEND de dados ... d) vc VAI se assegurar, dentro do possível, que a rotina será agendada para uma data/hora em que não estão sendo feitos grandes DMLs na tal tabela grande : a questão é que, para se assegurar que não há leitura suja, de dados não-comitados, durante DMLs a informação consistente é armazenada em undo blocks, que significam mais I/Os extras
[]s Chiappa