Comment puis-je réduire l'impact d'une i / o requête à forte intensité de longue durée dans PostgreSQL?

StackOverflow https://stackoverflow.com/questions/5361703

  •  27-10-2019
  •  | 
  •  

Question

Ce message suggère que je peux utiliser un curseur pour aller chercher à partir d'une requête à un taux étranglé. Comment puis-je faire cela? Mon objectif est de réduire l'impact de cette requête à faible priorité sur d'autres questions prioritaires de plus.

Était-ce utile?

La solution

Vous pouvez le faire en déclarant curseurs côté serveur, avec la commande DECLARE:

DECLARE my_cursor CURSOR FOR select * from foo;

Et puis lire ses résultats en utilisant la commande FETCH à plusieurs reprises:

FETCH 10 FROM my_cursor;

En dormant entre la commande Fetch, vous limitez efficacement à quelle vitesse la requête peut exécuter.

Une fois que vous avez terminé, vous pouvez vous débarrasser du curseur en appelant COMMIT, ROLLBACK ou CLOSE my_cursor

Prenez note que certains types de requêtes ne peuvent pas être directement émis en continu via un curseur, mais seront RAN à la fin avant de produire la première ligne de sortie. Les requêtes avec des agrégats de hachage et de grandes sortes non indexées sont un exemple. Vous pouvez réduire le paramètre cursor_tuple_fraction (par défaut 0,1) pour décourager le planificateur de choisir ce type de plans, mais ce n'est pas toujours possible.

Autres conseils

La seule façon que je connaisse à gaz un curseur est de faire un peu de travail, puis le sommeil.

CREATE OR REPLACE FUNCTION test_cursor()
  RETURNS void AS
$BODY$

DECLARE
    curs1 CURSOR FOR SELECT select * from information_schema.tables limit 5;

BEGIN

    FOR example_variable IN curs1 LOOP
        -- Other pgsql statements

        -- sleep for one second
        perform pg_sleep(1);

    END LOOP;

END;
$BODY$
  LANGUAGE plpgsql;

Le code source de pg_dump comprend pseudo-code pour son algorithme « de gaz », mais juste dormir pour une période fixe est probablement assez bon.

* If throttle is non-zero, then
*      See how long since the last sleep.
*      Work out how long to sleep (based on ratio).
*      If sleep is more than 100ms, then
*          sleep
*          reset timer
*      EndIf
* EndIf
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top