Vous n'êtes pas identifié(e).
Bonjour
Nous constatons une déperdition importante de performance entre la 8.4 et la 9.3 sur le lock explicite
Nous travaillons sur une table nommée "chrono" pour l'exemple, qui contient moins de 50 lignes
Le code concerné est le suivant :
-----------------------------------------------------
begin
for 1 to 1000
select * from chrono where [where_condition] FOR UPDATE
do stuff (or not…..)
update chrono set [set_clause] where [where_condition]
end for
commit
--------------------------------------------------------
En 8.4, no problem: le temps de chaque boucle reste homogène, du début à la fin.
En 9.3, il y a une déperdition exponentielle !
Nos tests montrent qu'une façon "simple" de résoudre le problème serait de faire un commit après chaque update de chrono, afin de "libréer" le lock.
Mais, mais, mais: faire cela a d'énormes conséquences par ailleurs, sur notre application (pour faire simple, une réécriture très lourde, chronophage et impactante)
Une idée ou une explication ?
Merci
Dernière modification par krile (29/11/2014 11:09:03)
Hors ligne
Un test très rapide de mon côté indique les mêmes durées entre une 8.4 et une 9.3. 600ms dans le cas de la transaction globale, et 9s dans le cas des transactions unitaires. Bref, rien de bien nouveau. Il doit y avoir quelque chose de spécifique à votre application que vous n'avez pas partagé avec nous.
Guillaume.
Hors ligne
Bonjour, et merci pour cette réponse,
La déperdition se manifeste avec une nombre d'itérations > 1000, voire > 10 000. La déperdition semble alors exponentielle.
Voici le code utilisé, et exécuté directement via pgadmin, sur une base identique 8.4 et 9.3.
La procédure est lancée via un "select * from jpi_test_perf_chronos()" tout simple
A noter que les tables etablissement et param_chrono contiennent moins de 50 enreg :
---------------------------------------------------------
CREATE OR REPLACE FUNCTION jpi_test_perf_chronos()
RETURNS VOID AS
$BODY$
DECLARE
x INTEGER := 0;
y INTEGER;
BEGIN
LOOP
select 1 from param_chrono into y where chron_table = 'facture' for UPDATE;
select 1 into y from etablissement limit 1;
update param_chrono set chron_chrono = chron_chrono where chron_table = 'facture';
x := x +1 ;
IF x >= 9999 THEN
EXIT;
END iF ;
END LOOP;
RETURN;
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
------------------------------------------------------------------------------
En 8.4 => 4300 ms
En 9.3 => 19 500 ms (...)
Dernière modification par krile (01/12/2014 11:41:13)
Hors ligne
J'ai fait de nouveau un test sur mon portable avec ce script :
create database test;
\c test
create language plpgsql;
CREATE TABLE param_chrono (chron_table text, chron_chrono integer);
INSERT INTO param_chrono SELECT 'facture', i FROM generate_series(1, 10) AS i;
CREATE TABLE etablissement ();
CREATE OR REPLACE FUNCTION f1()
RETURNS VOID AS
$BODY$
DECLARE
x INTEGER := 0;
y INTEGER;
BEGIN
LOOP
select 1 from param_chrono into y where chron_table = 'facture' for UPDATE;
select 1 into y from etablissement limit 1;
update param_chrono set chron_chrono = chron_chrono where chron_table = 'facture';
x := x +1 ;
IF x >= 9999 THEN
EXIT;
END IF;
END LOOP;
RETURN;
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
\timing
SELECT f1();
SELECT f1();
SELECT f1();
Les résultats en 8.4 :
Time: 28289.002 ms
Time: 33390.830 ms
Time: 24323.990 ms
Les résultats en 9.3 :
Time: 30775.129 ms
Time: 43561.052 ms
Time: 39700.712 ms
Guillaume.
Hors ligne
De mon côté, en utilisant le même code que vous (et les mêmes tables)
8.4 :
--27 550
--36 318
--32 589
--33 010
--38 720
--56 379
--43 696
--28 704
--29 031
--34 710
9.3 :
--53 758
--44 179
--39 110
--37 503
--51 059
--68 345
--62 526
--41 372
--43 275
Je ne suis pas sur que l'on puisse en tirer quoi que ce soit. Éventuellement que cela est quand-même plus long en 9.3.
Ceci étant dit, nous avons trouvé l'explication à la dégradation exponentielle que nous constations en 9.3. Il s'agissait d'une différence entre les deux postgres.conf
Bref, pour conclure sur la batterie de tests du jour :
- la 9.3 reste plus lente sur la gestion de slock explicite
- la dégradation exponentielle se corrige via "bon" paramétrage du postgres.conf
Hors ligne
Pour compléter ce qui a été dit plus haut (étant un collègue de krile) :
Nos tests ont été faits sur Windows (7, 64 bits), avec des version 9.3 32 bits et 64 bits, ainsi que 9.4 RC1 (64 bits).
Hors ligne
Il serait intéressant de savoir quelle était la mauvaise configuration, et quelle était la bonne configuration...
Guillaume.
Hors ligne
Finalement, fausse joie !
Les derniers tests n'étaient pas probants, notamment concernant la perte exponentielle que nous ne constations plus.
En effet, nous n'avions plus, dans notre jeu de test, de ligne concernée par le select for update (sic)
Le problème reste donc entier.
Hors ligne
@Gleu : le problème n'est pas résolu mais la cause est trouvée : il s'agit du pilote ODBC.
En accès direct : pas de problème (que nous ne pouvons pas utiliser dans notre application, je passe les détails).
Avec le pilote ODBC (unicode, version 8.4.2 et 9.3.4) vs PG 8.4 : pas de problème.
Même application, même pilotes ODBC (v8.4.2 ou v9.3.4) vs PG 9.3 ou 9.4 RC1 : augmentation exponentielle du temps de traitement dans le cas décrit ci-dessus.
Dernière modification par nterrien (02/12/2014 15:22:26)
Hors ligne
Là, il faudrait voir directement avec les développeurs de psqlodbc. Je ne connais pas assez pou rêtre d'une quelconque aide.
Guillaume.
Hors ligne
Oui, c'est que l'on s'est dit aussi.
Merci pour le coup de main en tout cas !
Hors ligne
Donc le problème a été rapporté sur la liste psqlodbc : http://www.postgresql.org/message-id/52 … matique.fr
La solution a été trouvée par Heikki, suite à une idée d'Alvaro : http://www.postgresql.org/message-id/54 … vmware.com (passé en protocole 7.4-0 pour éviter l'ajout de SAVEPOINT qui ont un coût assez fort dans l'exécution d'une transaction).
Guillaume.
Hors ligne