Selecionar registros de 500.000 em 500.000

9 respostas
Zeed01

Boa tarde Colegas !

Tenho uma necessidade de criar um cursor que retorne de 500.000 em 500.000 registros.
Explicando, seriam várias procedures, cada uma com um cursor, então a primeira processaria do registro 1 ao 500.000, a segunda do 500.001 ao 1.000.000, a terceira do 1.000.001 ao 1.500.000, e assim por diante.
Alguem sabe como fazer isso sem criar uma coluna especifica para esse controle ?

Obrigado a todos.

[]s

9 Respostas

D

Qual o BD?

Zeed01

Boa tarde Colegas !

Desculpe… o banco é Oracle 8.

[]s

D

Eu fiz no SQL Server da seguinte maneira

Como o uso de cursores não é muito aconselhável eu criei um da seguinte maneira:

Criei uma variável do tipo TABLE com os campos iguais ao da tabela de origem, desse modo tudo fica na RAM, e portanto melhora o desempenho. Mas não sei se é possível criar isso no Oracle, se não for possível crie uma tabela temporária mesmo.

Carregue essa tabela com os registros que deseja, depois utilize um while para pegar um registro de cada vez deletando este registro, dessa forma você cria um cursor, onde pode pegar os registros que deseja na quantidade necessária.

T

http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/pseudocolumns009.htm

A documentação que lhe passei é para o Oracle 11 mas isso existe há muito tempo (acho que na época do Oracle 6 ou 7 isso já existia).

Zeed01

Boa noite Colegas !

thingol:

Acessei o link, mas não encontrei a solução para o meu problema…
pq o rownum é criado para cada select que vc faz…

Talvez eu não tenha sido muito claro no meu problema…
Imagine que preciso criar 20 cursores, cada um pegando um pacote de 500.000 registros…
se eu faço:
cursor 1: select * from tabela where rownum < 500000
cursor 2: select * from tabela where rownum between 500001 and 1000000

não funciona…

Se puder me ajudar fico muito grato !

[]s

bombbr

Utilize a função analítica ROW_NUMBER(), conforme exemplo abaixo.

SELECT * FROM (
  SELECT ROW_NUMBER() OVER (ORDER BY SS.ID) LINHA, SS.* FROM TABELA SS
) X
WHERE X.LINHA BETWEEN 1 AND 500000


SELECT * FROM (
  SELECT ROW_NUMBER() OVER (ORDER BY SS.ID) LINHA, SS.* FROM TABELA SS
) X
WHERE X.LINHA BETWEEN 500001 AND 1000000
Zeed01

Bom dia Colegas !

Obrigado pelas dicas, mas infelizmente, pelo que vi, com esse select:

SELECT * FROM (   
  SELECT ROW_NUMBER() OVER (ORDER BY SS.ID) LINHA, SS.* FROM TABELA SS   
) X   
WHERE X.LINHA BETWEEN 1 AND 500000   

SELECT * FROM (   
  SELECT ROW_NUMBER() OVER (ORDER BY SS.ID) LINHA, SS.* FROM TABELA SS   
) X   
WHERE X.LINHA BETWEEN  500001 AND 1000000

O Oracle esta fazendo um full scan em TABELA que no meu caso tem 11 Milhoes de registros… o que torna inviavel a utilização.

Alguem sabe me dizer se com GTT eu poderia ter um ganho, minha idéia, criar uma tabela temporária na memória com as colunas ROWNUM e ID da tabela, depois nos cursores que quero criar com 500.000 registros cada faço um join da tabela temporaria com a tabela real pelo ID e filtrando pelo rownum…
Pensei que dessa forma teria que fazer o full scan na tabela principal de 11 milhoes somente uma vez para montar a tabela temporário…

Mesmo assim obrigado a todos !

[]s

bombbr

Zeed01:
Bom dia Colegas !

SELECT * FROM (   
  SELECT ROW_NUMBER() OVER (ORDER BY SS.ID) LINHA, SS.* FROM TABELA SS   
) X   
WHERE X.LINHA BETWEEN 1 AND 500000

O Oracle esta fazendo um full scan em TABELA que no meu caso tem 11 Milhoes de registros… o que torna inviavel a utilização.
[]s

Zeed01,

Crie um indice para o campo da cláusula OVER (ORDER BY SS.ID) . O ideal a que seja a chave primária, assim o Oracle não irá fazer FULL SCAN.

Zeed01

Bom dia Colegas !

bombbr:

Infelizmente este campo já é a PK da tabela…
No plano de execução de execução aparece INDEX FULL SCAN e o custo esta dando 430.000.
Nesse INDEX FULL SCAN esta pegando as 11 Milhoes de linhas…

Obrigado pela ajuda.

[]s

Criado 3 de setembro de 2008
Ultima resposta 4 de set. de 2008
Respostas 9
Participantes 4