Je dois dupliquer des valeurs d'une table à une autre (schémas de table identiques). Quoi de mieux (performance): p>
mise à jour: J'ai fait un petit test sur la table avec presque 3k rangées. Drop and Create donne environ 60 ms vs Supprimer et insérer - environ 30 ms. P>
4 Réponses :
Si vous parlez de l'exécution du Il en va de même pour Dans tous les cas. Lors de la copie de grandes tables, désactivez toujours les déclencheurs, les indices et les contraintes pour gagner des performances. P> Insérer code> s manuellement, un par un, puis goutte code> / Créer code> sera beaucoup plus rapide. En outre, lorsque vous utilisez Créer une table comme code>, il ne sera que em> copier les définitions de la colonne. Les indices et d'autres contraintes seront pas em> être copiés. Cela accélérera le processus de copie énormément em>. Mais vous devrez vous rappeler de les ré-créer sur la nouvelle copie une fois que vous avez terminé. P>
Sélectionnez dans CODE>. Ils sont fonctionnellement identiques. Ils ont juste des noms différents. P>
Utilisez tronquée au lieu de la table de goutte ou supprimez lorsque vous devez vous débarrasser de tous les enregistrements d'une table. Avec tronquage, vous pouvez toujours utiliser des déclencheurs dans PostgreSQL et les autorisations sont plus faciles à définir et à entretenir. P>
Comme une goutte, TronCate a également besoin d'une serrure de table. P>
Je vois quatre moyens utiles de remplacer le contenu de la table. Aucun d'entre eux n'est "évidemment juste", mais cela dépend de vos besoins.
(dans une seule transaction) pro: strong> Meilleur concurrence: ne verrouille pas d'autres transactions Accès à la table, car elle exploite le MVCC de Postgres. P>
pro: strong> le plus rapide pour les tables plus petites. Causes moins d'écriture I / O que n ° 1 p>
con: strong> exclut tous les autres lecteurs - autres transactions La lecture de la table devra attendre. p> li>
pro: strong> le plus rapide pour les grandes tables, car la création d'index avec con: strong> même que # 2 p> li>
le commutateur. Créez deux tables identiques Supprimer de FOO; Insérer dans FOO SELECT ... CODE> P>
tronqua foo; Insérer dans FOO SELECT ... CODE> P>
tronquez FOO code>, déposez tous les index sur table, Insérer dans FOO SELECT ... CODE>, recréez tous les index. P>
Créer Index code> est plus rapide que la mise à jour progressivement. P>
FOO CODE> et FOO_TMP CODE> P>
TRUNCATE foo_tmp;
INSERT INTO foo_tmp SELECT ...;
ALTER TABLE foo RENAME TO foo_tmp1;
ALTER TABLE foo_tmp RENAME TO foo;
ALTER TABLE foo_tmp1 RENAME TO foo_tmp;
Je devais renommer / déposer mes index après avoir fait le numéro 4 et le n ° 3 combiné. Les index primaires-clés sont renommés automatiquement, d'autres ne le sont pas. Le temps total pour déposer et reconstruire ~ 800.000 rangs d'une vue allait de 90 à environ 20 ans. Merci pour le conseil.
Cette réponse contient-elle toujours avec les dernières versions de PostgreSQL comme 10+?
@PirateApp Il y a une méthode supplémentaire pour faire cela en utilisant Insert ... sur la mise à jour des conflits, etc., avec ses propres compromis. En dehors de cela, il y a eu des optimisations plus petites, mais ce que j'ai écrit est toujours pertinent.
Voici les horaires (comparatifs) pour la réponse de Intgr (voir le code ci-dessous):
index de goutte / tronquage / insert / créer index - 13 sec. p>
-- preparations
drop table if exists temp_refresh_experiment;
-- million random strings
create table temp_refresh_experiment as
select
upper(substr(md5(random()::text), 0, 25)) as some_column
FROM
generate_series(1,1000000) i;
-- create index
create index temp_refresh_experiment_ix on temp_refresh_experiment(some_column)
;
-- 1. delete/insert
delete from temp_refresh_experiment;
insert into temp_refresh_experiment(some_column)
select
upper(substr(md5(random()::text), 0, 25)) as some_column
FROM
generate_series(1,1000000) i;
-- 36 secs
-- 2. truncate/insert
truncate temp_refresh_experiment;
insert into temp_refresh_experiment(some_column)
select
upper(substr(md5(random()::text), 0, 25)) as some_column
FROM
generate_series(1,1000000) i;
-- 19 sec
-- 3. drop index/truncate/insert/create index
drop index if exists temp_refresh_experiment_ix;
truncate temp_refresh_experiment;
insert into temp_refresh_experiment(some_column)
select
upper(substr(md5(random()::text), 0, 25)) as some_column
FROM
generate_series(1,1000000) i;
create index temp_refresh_experiment_ix on temp_refresh_experiment(some_column)
;
-- 13 sec
Mon intuition me dit que le moyen le plus rapide serait tronquer et insérer, car Supprimera toutes les rangées et les supprime individuellement, alors que le tronquage tout simplement vide la table sans conditions possibles.
3k rangées .... Sérieusement? .... et vous parlez de performance? ... Optimisation prématurée Toute personne? Lorsque j'ai lu votre message initial, je pensais que vous parliez de plusieurs millions de rangées. 3k rangées est rien i>. Pour les rangées de 3k, vous n'avez probablement même pas besoin d'une DB;)
Cela dépend de la fréquence à laquelle il a besoin de le faire et à quelle fréquence les transactions simultanées doivent-elles y accéder, n'est-ce pas? :)