Agrégats dans la base de données - traitement efficace du flux de «faits»

Supposons que vous deviez traiter un grand nombre (non, pas que ... GRAND) d'enregistrements dans PostgreSQL afin de calculer certains agrégats. Dans l' article précédent , nous avons analysé différentes options pour organiser cela, et dans cet article nous verrons comment ne pas bloquer personne en particulier , y compris le «flux entrant» de données.





Par exemple, il peut s'agir de recalculer les soldes et de maintenir les ventes consolidées pour les marchandises avec leurs expéditions constantes, ou d'agréger les soldes et les chiffres d'affaires pour les comptes comptables, avec des changements massifs dans les transactions, ou autre chose ... Dans tout système de gestion, il y aura une diapositive , et VLSI ne fait pas non plus exception.





Mais toutes ces situations ont un point commun: le nombre de changements est  bien  supérieur au nombre d'agrégats cibles. Par exemple: des milliers de marchandises, chacune avec des dizaines de milliers d'expéditions par jour.





Dans d'autres considérations, nous nous appuierons sur ce modèle de «Amazon avec des marchandises».





Objectif - ventes quotidiennes consolidées

Nous voulons avoir des agrégats pour les ventes dans le contexte du  produit / jour / quantité .





Concrètement, dans ce cas, nous réaliserons des agrégats "directement dans la base de données" afin de pouvoir les   recevoir rapidement et globalement pour différents rapports.





, , , - ClickHouse, . , , , , , , , ...





- ( ), 2PC- , - .





, -   ,  , - , . ,  "" ,   .





?.. ...





    , ,  "" - - , - - ,   "" ,   ""  .





  - "", - "--".





"" , ,    ().





""

"". , - , .





  ""  .  INSERT, UPDATE DELETE



, "" -  INSERT



. , PostgreSQL  , - unique-.





, " " ,   - . , - , "" flow-.





"" ""

flow- ,   / ""  "- - ".





""? " , " -   58    .





,   , . , --, ,   .





, , , "" - …   fail, :





DELETE FROM flow WHERE (it, dt) = (1, '2018-07-29') RETURNING *;
      
      



, - " ". , 1K/, 10K/.





:





SET statement_timeout = 1000;
      
      



, ! , , - flow- ,   . …





, "" , . " ", .





, flow , ,   "" .





, , ! ,   :





DECLARE curs CURSOR FOR SELECT ctid, * FROM flow WHERE (it, dt) = (1, '2018-07-29') FOR UPDATE;
--  , ,    
    FETCH %d FROM curs;
    DELETE FROM flow WHERE ctid = ANY(...);
      
      



flow  ctid - ""   .





SAVEPOINT

, "". %d FETCH? - , - ... ?





PostgreSQL " "  SAVEPOINT/ROLLBACK TO, "" .





:





  1.  ( - , ).





  2. .





  3. -   COMMIT' .





  4.   , - COMMIT'.





  5.   ,  - , "" ( , ).





  6. !





BEGIN;
  DECLARE curs CURSOR FOR SELECT ctid, * FROM flow WHERE (it, dt) = (1, '2018-07-29') FOR UPDATE;

  FETCH 1 FROM curs;
  DELETE FROM flow WHERE ctid = ANY(...);
  -- processing
  INSERT INTO agg ...
  SAVEPOINT _1;
  
  FETCH 2 FROM curs;
  DELETE FROM flow WHERE ctid = ANY(...);
  -- processing
  INSERT INTO agg ...
  SAVEPOINT _2;
  
  FETCH 4 FROM curs;
  DELETE FROM flow WHERE ctid = ANY(...);
  -- processing...
  INSERT INTO agg ...
  -- oops! timeout exception!
  ROLLBACK TO _2;
  
  CLOSE curs;
COMMIT;
      
      



. , , !








All Articles