Paginação de forma eficiente

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

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.

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.

[quote=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.

[/quote]

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

[quote=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.[/quote]

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

[quote]
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[/quote]

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);

“…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.

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.

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.

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.

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.

[quote=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.[/quote]

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:

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

[quote=microfilo]Qual banco?
Se for oracle, tente trocar por count(null)[/quote]

postgre

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