Delete

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Delete

Danilo Silva
Pessoal,

Qual seria a melhor prática para deletar 20 mil registros em uma tabela com 1,5 milhões de registros, vale ressaltar que o campo condicional do delete é a pk da tabela:

a) Deletar os 20 mil de uma só vez com a condição "IN" no WHERE;
b) Fazer um loop na aplicação e deletar um por vez;
c) Outra técnica (qual?);

Existe alguma forma de melhorar a rapidez do delete? Algum parâmetro no .conf?

[]s
Danilo

_______________________________________________
pgbr-geral mailing list
[hidden email]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Reply | Threaded
Open this post in threaded view
|

Re: Delete

Fábio Telles Rodriguez
vamos imaginar que a tabela 't' tem o campo 'id' que você quer remover as 20 mil linhas:

postgres=# create table t (id integer);
CREATE TABLE
postgres=# insert into t select * from generate_series(1,1500000);
LOG:  temporary file: path "pg_tblspc/581531196/PG_9.3_201306121/pgsql_tmp/pgsql_tmp29753.0", size 21000000
INSERT 0 1500000

Agora vou criar uma tabela temporária que tenha 20 mil registros aleatórios. Serão os registros que eu vou querer apagar da tabela 't'

postgres=# create temporary table f (id integer);
CREATE TABLE
postgres=# insert into f select round(random()*1500000) from generate_series(1,20000);
INSERT 0 20000


Agora eu faço o DELETE dos registros que escolhi:

postgres=# delete from t where exists (select 1 from f where f.id=t.id);
DELETE 19866

Ou seja, eu prefiro fazer um SUBSELECT para apagar tudo.


Em 18 de dezembro de 2017 17:15, Danilo Silva <[hidden email]> escreveu:
Pessoal,

Qual seria a melhor prática para deletar 20 mil registros em uma tabela com 1,5 milhões de registros, vale ressaltar que o campo condicional do delete é a pk da tabela:

a) Deletar os 20 mil de uma só vez com a condição "IN" no WHERE;
b) Fazer um loop na aplicação e deletar um por vez;
c) Outra técnica (qual?);

Existe alguma forma de melhorar a rapidez do delete? Algum parâmetro no .conf?

[]s
Danilo

_______________________________________________
pgbr-geral mailing list
[hidden email]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral



--
Atenciosamente,
Fábio Telles Rodriguez
blog: http://savepoint.blog.br
e-mail / gtalk / MSN: [hidden email]
Skype: fabio_telles

Timbira - A empresa brasileira de Postgres

_______________________________________________
pgbr-geral mailing list
[hidden email]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Reply | Threaded
Open this post in threaded view
|

Re: Delete

Danilo Silva
Em 18 de dezembro de 2017 18:32, Fábio Telles Rodriguez <[hidden email]> escreveu:
vamos imaginar que a tabela 't' tem o campo 'id' que você quer remover as 20 mil linhas:

postgres=# create table t (id integer);
CREATE TABLE
postgres=# insert into t select * from generate_series(1,1500000);
LOG:  temporary file: path "pg_tblspc/581531196/PG_9.3_201306121/pgsql_tmp/pgsql_tmp29753.0", size 21000000
INSERT 0 1500000

Agora vou criar uma tabela temporária que tenha 20 mil registros aleatórios. Serão os registros que eu vou querer apagar da tabela 't'

postgres=# create temporary table f (id integer);
CREATE TABLE
postgres=# insert into f select round(random()*1500000) from generate_series(1,20000);
INSERT 0 20000


Agora eu faço o DELETE dos registros que escolhi:

postgres=# delete from t where exists (select 1 from f where f.id=t.id);
DELETE 19866

Ou seja, eu prefiro fazer um SUBSELECT para apagar tudo.

​A minha tabela possui uma outra com históricos​, então eu tenho o seguinte cenário:
Tabela principal com 79 colunas, 1,5 milhões de registros e 596 MB de tamanho;
Tabela de historico com 20 colunas, 10 milhões de registros e 1,2 GB de tamanho;

Para excluir os registros da tabela principal, eu tenho que excluir primeiro na tabela de historicos, então eu excluí os 20 mil registros utilizando o operador "IN" e o delete foi rápido, porém, na tabela principal não, o campo utilizado no delete não é a PK mas um índice único. Será que pode ter ocorrido algum problema na tabela principal como um índice corrompido?

No explain utilizando o "IN" eu tenho: Delete on tabela_a  (cost=25.50..96449.56 rows=20059 width=6)
​Utilizando o método proposto pelo Telles eu tenho: ​Delete on tabela_a  (cost=356.43..1324.56 rows=843680 width=12)


[]s
Danilo

_______________________________________________
pgbr-geral mailing list
[hidden email]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
l
Reply | Threaded
Open this post in threaded view
|

Re: Delete

l
In reply to this post by Danilo Silva
Le lun. 18 déc. 2017 à 17:15, Danilo Silva
<[hidden email]> a écrit :
>
> Qual seria a melhor prática para deletar 20 mil registros em uma
> tabela com 1,5 milhões de registros, vale ressaltar que o campo
> condicional do delete é a pk da tabela:
>
> a) Deletar os 20 mil de uma só vez com a condição "IN" no WHERE;
> b) Fazer um loop na aplicação e deletar um por vez;

Lembra que SQL é orientado a conjuntos (baseado no modelo relacional,
que combina lógica dos predicados com teoria dos conjuntos);
naturalmente, geralmente será bem melhor trabalhar com conjuntos que
com iterações de operações individuais.


--
skype:leandro.gfc.dutra?chat      Yahoo!: ymsgr:sendIM?lgcdutra
+55 (61)  3546 7191             gTalk: xmpp:[hidden email]
+55 (61) 99302 2691       ICQ/AIM: aim:GoIM?screenname=61287803
BRAZIL GMT−3  MSN: msnim:chat?contact=[hidden email]

_______________________________________________
pgbr-geral mailing list
[hidden email]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Reply | Threaded
Open this post in threaded view
|

Re: Delete

Fábio Telles Rodriguez
In reply to this post by Danilo Silva
​A minha tabela possui uma outra com históricos​, então eu tenho o seguinte cenário:
Tabela principal com 79 colunas, 1,5 milhões de registros e 596 MB de tamanho;
Tabela de historico com 20 colunas, 10 milhões de registros e 1,2 GB de tamanho;

Para excluir os registros da tabela principal, eu tenho que excluir primeiro na tabela de historicos, então eu excluí os 20 mil registros utilizando o operador "IN" e o delete foi rápido, porém, na tabela principal não, o campo utilizado no delete não é a PK mas um índice único. Será que pode ter ocorrido algum problema na tabela principal como um índice corrompido?

No explain utilizando o "IN" eu tenho: Delete on tabela_a  (cost=25.50..96449.56 rows=20059 width=6)
​Utilizando o método proposto pelo Telles eu tenho: ​Delete on tabela_a  (cost=356.43..1324.56 rows=843680 width=12)

Rode o EXPLAIN ANALYZE ao invés do EXPLAIN simples. Outra coisa que pode ajudar é depois de fazer o INSERT na tabela 'f', rodar um ANALYZE na tabela 'f'. Assim o otimizador deverá fazer um trabalho melhor.

--
Atenciosamente,
Fábio Telles Rodriguez
blog: http://savepoint.blog.br
e-mail / gtalk / MSN: [hidden email]
Skype: fabio_telles

Timbira - A empresa brasileira de Postgres

_______________________________________________
pgbr-geral mailing list
[hidden email]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral