Paginação de forma eficiente

14 respostas
T

Caros colegas,

Estou montando uma páginação para um sistema.
Preciso saber a quantidade total de registros em uma tabela, a única forma que conhece é através de “SELECT count(pk) as total FROM table”, fazendo um teste é uma tabela com 600 k registros demorou 7 segundos, o que IMHO é muito lento. Alguem saberia outra forma de fazer isso

:wink:

  • estou utilizando Postgres

14 Respostas

B

Amigo,

Acredito que esta seja a única forma.
Você precisa retornar o total da tabela?
Se for o total tabela, se o PK for um campo incremental, retorne o max dele, assim terá o total de registro.
Não existe nenhuma clausula where?
Se tiver um clausula where, tenta criar um indice nessa PK, assim evita de fazer full na tabela e evitando um tempão.

afamorim

Meu velho, não seria o caso de vc olhar como vc esta fazendo??

se esta fazendo paginação no momemnto da consulta vc trará o registro e ja implementa um contador no while.

tb não seria o caso dessa consulta ter um filtro?

espero ter ajudado.

T

Byron:
Amigo,

Acredito que esta seja a única forma.
Você precisa retornar o total da tabela?
Se for o total tabela, se o PK for um campo incremental, retorne o max dele, assim terá o total de registro.
Não existe nenhuma clausula where?
Se tiver um clausula where, tenta criar um indice nessa PK, assim evita de fazer full na tabela e evitando um tempão.

Não tem where não, pq eu quero todos os registros da tabela.
“tenta criar um indice nessa PK” => PK ja é um indice! é o indice do registro

T

afamorim:
Meu velho, não seria o caso de vc olhar como vc esta fazendo??

se esta fazendo paginação no momemnto da consulta vc trará o registro e ja implementa um contador no while.

tb não seria o caso dessa consulta ter um filtro?

espero ter ajudado.

Filtros serão possíveis, mais de qualquer forma eu posso ter uma consulta sem filtro que iria trazer tds os registros. Eu faço uma consulta para poder fazer a paginação, pois preciso saber quantos registros existem.

Por ex. aqui no forum no rodapé de cada tópico vc encontra:
Ir para a página: 1, 2, 3 … 24, 25, 26 Próximo

Para ele chegar nesse 26 ele precisa contar os registros e dividir pela quantidade por pagina. Se fosse 10 por pagina ele puxou 260 / 10 = 26

B


Não tem where não, pq eu quero todos os registros da tabela.
“tenta criar um indice nessa PK” => PK ja é um indice! é o indice
do registro

Dá uma estudada sobre índice, vai perceber que pode ganhar muita velocidade. PK e índice são coisas diferentes.
Mas no seu caso o índice não vai ajudar em nada, pois vc vai fazer full na table.

O retorno do MAX é bem mais rápido. Se sua PK é numérica sequencial, manda retornar o MAX dela que vc terá o total de registro.
Entendeu?

Segue sintaxe de indices:

CREATE INDEX eixos_idx ON eixos USING gist (the_geom)

Onde:
CREATE INDEX -> cria o índice
eixos_idx -> nome para o seu índice
ON eixos -> define a tabela que se quer indexar
USING gist (the_geom) -> escolhe o índice a ser usado (gist) e o campo a que vai ser aplicado (the_geom)

Recomenda-se depois executar:

VACUUM ANALYZE nometabela nomecoluna;
SELECT UPDATE_GEOMETRY_STATS(nometabela, nomecoluna);

T

“…Se sua PK é numérica sequencial, manda retornar o MAX dela que vc terá o total de registro…” => ERRADO

Max retorna a PK do ultimo registro inserido, se eu tiver 10 registros sequencias iniciando de 1, e der um max ele vai retornar 10. Ok
Se eu apagar o 3 por ex. e fizer a mesma consulta ele vai retorna 10 novamente invés de 9.

B

Se você deleta os dados não funciona.
A sua única solução é o count mesmo.
Se a velocidade está te incomodando tanto, tem um trabalhão se não sei se vai compensar o ganho de velocidade.
Executa um job resultando o count e qd for pegar o cont geral, pega dessa tabela. No delete cria a trigrer para executar o job novamente.

T

pois é, essa foi uma alternativa que pensei mas realmente é um bom trabalho… Eu queria tipo uma property da tabela… um show alguma coisa… algo assim.

B

Pelo que vi na Internet, o Postgresql tem várias reclamações do count(*) ser lerdo. Colocam essa alternativa de criar um outra tabela e dar um update + 1 na trigger para cada alteração.
Trabalho mais com oracle e não sei se existe uma propriedade que retorne o número de linhas da table no Postgresql.

afamorim

Meu velho faça como falei a cima, em vez de fazer um select separado aproveite o o while para gerar um contador dos registros.

vc ainda pode fazer melhor prechendo a coleção com os registros quando chegar na pagina aonde vc for construir a paginação vc pega o size da coleção e controi o mesmo.

T

afamorim:
Meu velho faça como falei a cima, em vez de fazer um select separado aproveite o o while para gerar um contador dos registros.

vc ainda pode fazer melhor prechendo a coleção com os registros quando chegar na pagina aonde vc for construir a paginação vc pega o size da coleção e controi o mesmo.

Então meu querido, entenda o seguinte a tabela tem 690.000 registro.
Obviamente eu não vou exibir todos na tela, consequentimente não vou puxar todos e iterar o resulset, até pq utilizo Hibernate.
Eu queria apenas saber qual a quantidade de registros pra exibir o número de páginas, por isso o select count().

[s] Obrigado a todos :slight_smile:

Rubem_Azenha

Qual banco?
Se for oracle, tente trocar por count(null)

T

microfilo:
Qual banco?
Se for oracle, tente trocar por count(null)

postgre

T

teste, mais retornou count = 0.
com count(null)

Criado 26 de maio de 2006
Ultima resposta 26 de mai. de 2006
Respostas 14
Participantes 4