Happy Party ose disa rreshta kujtimesh për njohjen me seksionimin në PostgreSQL10

Parathënie ose si lindi ideja e seksionimit

Historia fillon këtu: A e mban mend si filloi gjithçka. Ishte e para herë dhe sërish. Pas sa i gjithë burimet për optimizimin e kërkesës ishin shteruar, u bë pyetja - çfarë do të ndodhë më pas? Kështu lindi ideja e seksionimit.

Happy Party ose disa rreshta kujtimesh për njohjen me seksionimin në PostgreSQL10

Një anë lirikale:
PikĂ«risht ‘nĂ« atĂ« moment’, sepse siç doli, ekzistonin rezerva tĂ« pashfrytĂ«zuara pĂ«r optimizim. Faleminderit asmm dhe Habrus!

Pra, si mund ta bëjmë klientin disi të kënaqur, ndihmuar së bashku që të rrisim aftësitë tona?

Nëse e thjeshtojmë deri në maksimum, atëherë, ka vetëm dy rrugë për të përmirësuar ndjeshëm performancën e databazës:
1) Rruga ekstensive - rritim burimesh, ndryshimi i konfiguracionit;
2) Rruga intensive - optimizimi i kërkesave

Pasi, të rikthehem, në atë moment nuk ishte e qartë se çfarë tjetër duhet ndryshuar në kërkesë për ta shpejtuar, u zgjodh rruga - ndryshimi i dizajnit të tabelave.

Tani - lind pyetja kryesore - çfarë dhe si do të ndryshojmë?

Kushtet fillestare

Së pari, kemi këtë ERD (e cila është treguar në mënyrë të thjeshtuar):
Happy Party ose disa rreshta kujtimesh për njohjen me seksionimin në PostgreSQL10
Karakteristikat kryesore:

  1. marrëdhëniet 'shumë-në-shumë'
  2. Tabela ka një çelës potencial për seksionim

Kërkesa fillestare:

SELECT
            p."PARAMETER_ID" as parameter_id,
            pc."PC_NAME" AS pc_name,
            pc."CUSTOMER_PARTNUMBER" AS customer_partnumber,
            w."LASERMARK" AS lasermark,
            w."LOTID" AS lotid,
            w."REPORTED_VALUE" AS reported_value,
            w."LOWER_SPEC_LIMIT" AS lower_spec_limit,
            w."UPPER_SPEC_LIMIT" AS upper_spec_limit,
            p."TYPE_CALCUL" AS type_calcul,
            s."SHIPMENT_NAME" AS shipment_name,
            s."SHIPMENT_DATE" AS shipment_date,
            extract(year from s."SHIPMENT_DATE") AS year,
            extract(month from s."SHIPMENT_DATE") as month,
            s."REPORT_NAME" AS report_name,
            p."SPARAM_NAME" AS SPARAM_name,
            p."CUSTOMERPARAM_NAME" AS customerparam_name
        FROM data w INNER JOIN shipment s ON s."SHIPMENT_ID" = w."SHIPMENT_ID"
             INNER JOIN parameters p ON p."PARAMETER_ID" = w."PARAMETER_ID"
             INNER JOIN shipment_pc sp ON s."SHIPMENT_ID" = sp."SHIPMENT_ID"
             INNER JOIN pc pc ON pc."PC_ID" = sp."PC_ID"
             INNER JOIN ( SELECT w2."LASERMARK" , MAX(s2."SHIPMENT_DATE") AS "SHIPMENT_DATE"
                          FROM shipment s2 INNER JOIN data w2 ON s2."SHIPMENT_ID" = w2."SHIPMENT_ID" 
                          GROUP BY w2."LASERMARK"
                         ) md ON md."SHIPMENT_DATE" = s."SHIPMENT_DATE" AND md."LASERMARK" = w."LASERMARK"
        WHERE 
             s."SHIPMENT_DATE" >= '2018-07-01' AND s."SHIPMENT_DATE" <= '2018-09-30' ;

Rezultatet e ekzekutimit në databazën testuese:
Kosto : 502 997.55
Koha e ekzekutimit: 505 sekonda.

ÇfarĂ« shohim? NjĂ« kĂ«rkesĂ« e zakonshme, pĂ«rmes sektorit temporal.
Të bëjmë një supozim të thjeshtë logjik: nëse ekziston një mostër e sektorit temporal, a mund të na ndihmojë? Saktë - seksionimi.

ÇfarĂ« duhet tĂ« seksionohet?

Në shikim të parë, zgjedhja është e qartë - seksionimi deklarativ i tabelës 'shipment' sipas çelësit 'SHIPMENT_DATE' (për të thënë shumë përpara - përfundimisht në prodhim rezultoi pak ndryshe).

Si të seksionojmë?

Ky pyetje gjithashtu nuk është shumë e komplikuar. Falë Zotit, në PostgreSQL 10, tani ka një mekanizëm të kuptueshëm për seksionimin.
Pra:

  1. Ruajmë dump-in e tabelës fillestare - pg_dump source_table
  2. Fshi tabelën fillestare - drop table source_table
  3. KrijojmĂ« tabelĂ«n prind me seksionim sipas ĐŽĐžĐ°ĐżĐ°Đ·ĐŸĐœit - create table source_table
  4. Krijojmë seksionet - create table source_table, create index
  5. Importojmë dump-in e krijuar në hapin 1 - pg_restore

Skripte për seksionimin

Për thjeshtësi dhe lehtësi, hapat 2, 3, 4 u bashkuan në një skript.

Pra:
Ruajmë dump-in e tabelës fillestare

pg_dump postgres --file=/dump/shipment.dmp --format=c --table=shipment --verbose > /dump/shipment.log 2>&1

Fshi tabelĂ«n fillestare + Krijo tabelĂ«n prind me seksionim sipas ĐŽĐžĐ°ĐżĐ°Đ·ĐŸĐœit + Krijo seksionet

--create_partition_shipment.sql
do language plpgsql $$
declare 
rec_shipment_date RECORD ;
partition_name varchar;
index_name varchar;
current_year varchar ;
current_month varchar ;
begin_year varchar ;
begin_month varchar ;
next_year varchar ;
next_month varchar ;
first_flag boolean ;
i integer ;
begin
  RAISE NOTICE 'KRIJO TABEL TEMPORARE PËR DATAT E DËRGESËS';
  CREATE TEMP TABLE tmp_shipment_date as select distinct "SHIPMENT_DATE" from shipment order by "SHIPMENT_DATE" ;

  RAISE NOTICE 'SHTO TABELËN e dĂ«rgesave';
  drop table shipment cascade ;
  
  CREATE TABLE public.shipment
  (
    "SHIPMENT_ID" integer NOT NULL DEFAULT nextval('shipment_shipment_id_seq'::regclass),
    "SHIPMENT_NAME" character varying(30) COLLATE pg_catalog."default",
    "SHIPMENT_DATE" timestamp without time zone,
    "REPORT_NAME" character varying(40) COLLATE pg_catalog."default"
  )
  PARTITION BY RANGE ("SHIPMENT_DATE")
  WITH (
      OIDS = FALSE
  )
  TABLESPACE pg_default;

  RAISE NOTICE 'KRIJO NËN TABELAT PËR TABELËN e dĂ«rgesave';

  current_year:='0';
  current_month:='0';

  begin_year := '0' ;
  begin_month := '0'  ;
  next_year := '0' ;
  next_month := '0'  ;

  FOR rec_shipment_date IN SELECT * FROM tmp_shipment_date LOOP
      
      RAISE NOTICE 'SHIPMENT_DATE=%',rec_shipment_date."SHIPMENT_DATE";
      
      current_year := date_part('year' ,rec_shipment_date."SHIPMENT_DATE");
      current_month := date_part('month' ,rec_shipment_date."SHIPMENT_DATE") ; 

      IF to_number(current_month,'99') = to_date( begin_year||'.'||begin_month, 'YYYY.MM') AND 
         to_date( current_year||'.'||current_month, 'YYYY.MM') < to_date( next_year||'.'||next_month, 'YYYY.MM') AND 
         NOT first_flag 
      THEN
         CONTINUE ; 
      ELSE
       --Kufij të rinj vetëm për herën e dytë dhe më pas 
       begin_year := current_year ;
       begin_month := current_month ;   
   
        IF current_month = '12' THEN
          next_year := date_part('year' ,rec_shipment_date."SHIPMENT_DATE" + interval '1 year') ;
        ELSE
          next_year := current_year ;
        END IF;
     
       next_month := date_part('month' ,rec_shipment_date."SHIPMENT_DATE" + interval '1 month') ;

      END IF;      

      partition_name := 'shipment_shipment_date_'||begin_year||'-'||begin_month||'-01-'|| next_year||'-'||next_month||'-01'  ;
 
     EXECUTE format('CREATE TABLE ' || quote_ident(partition_name) || ' PARTITION OF shipment FOR VALUES FROM ( %L ) TO ( %L )  ' , current_year||'-'||current_month||'-01' , next_year||'-'||next_month||'-01'  ) ; 

      index_name := partition_name||'_shipment_id_idx';
      RAISE NOTICE 'EMRI I INDICES =%',index_name;
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_ID") TABLESPACE pg_default ' ) ; 

      --Hiq flag-un për herë të parë
      first_flag := false ;
   
  END LOOP;

end
$$;

Importojmë dump-in

pg_restore -d postgres --data-only --format=c --table=shipment --verbose  shipment.dmp > /tmp/data_dump/shipment_restore.log 2>&1

Kontrollojmë rezultatet e sekcionimit

ÇfarĂ« kemi si rezultat? Teksti i plotĂ« i planit tĂ« ekzekutimit Ă«shtĂ« i gjatĂ« dhe i mĂ«rzitshĂ«m, ndaj mund tĂ« kufizohemi me numrat pĂ«rfundimtarĂ«.

Ishte

Kosto: 502 997.55
Koha e ekzekutimit: 505 sekonda.

Nisi

Kosto: 77 872.36
Koha e ekzekutimit: 79 sekonda.

NjĂ« rezultat shumĂ« i mirĂ«. UlĂ«m kostot dhe kohĂ«n e ekzekutimit. Prudja Ă«shtĂ« qĂ« pĂ«rdorimi i sekcionimit jep efektin e pritur dhe pĂ«rgjithĂ«sisht — pa surpriza.

Të gëzojmë klientin

Rezultatet e testimit iu paraqitĂ«n klientit pĂ«r shqyrtim. Pas shqyrtimit, ata dhanĂ« njĂ« verdikt tĂ« papritur: "Fantastike, sekciononi tabelĂ«n 'data'.”

Po, por ne po shqyrtonim një tabelë krejt tjetër, 'shipment', tabela 'data' nuk ka fushën 'SHIPMENT_DATE'.

Nuk ka problem, shtoni, ndryshoni. E rëndësishme është që klienti të jetë i kënaqur me rezultatin, detajet e realizimit nuk janë aq të rëndësishme.

Sekcionojmë tabelën kryesore 'data'

Në përgjithësi nuk kishte ndonjë vështirësi të veçantë. Megjithatë, algoritmi i sekcionimit përfundimisht pati disa ndryshime.

Shtojmë kolonën 'SHIPMENT_DATA' në tabelën 'data'

psql -h host -U database -d user
=> ALTER TABLE data ADD COLUMN "SHIPMENT_DATE" timestamp without time zone ;

Popullojmë të dhënat e kolonës 'SHIPMENT_DATA' në tabelën 'data', me vlerat e kolonës së njëjtë nga tabela 'shipment'

-----------------------------
--update_data.sql
--përditësim për tabelën 'data' të ndryshuar me vlerat e 'shipment_data' nga tabela 'shipment'
--version 1.0
do language plpgsql $$
declare 
rec_shipment_data RECORD ;
shipment_date timestamp without time zone ; 
row_count integer ;
total_rows integer ;
begin

  select count(*) into total_rows from shipment ; 
  RAISE NOTICE 'Totali %',total_rows;
  row_count:= 0 ;

  FOR rec_shipment_data IN SELECT * FROM shipment LOOP

   update data set "SHIPMENT_DATE" = rec_shipment_data."SHIPMENT_DATE" where "SHIPMENT_ID" = rec_shipment_data."SHIPMENT_ID";
   
   row_count:=  row_count +1 ;
   RAISE NOTICE 'Numri i rreshtave = % , nga %',row_count,total_rows;
  END LOOP;

end
$$;

Ruajmë dump-in e tabelës 'data'

pg_dump postgres --file=/dump/data.dmp --format=c --table=data --verbose > /dump/data.log 2>&1

Rikrijojmë tabelën e sekcionuar 'data'

--create_partition_data.sql
--krijo parti për tabelën "të dhënat e wafer" sipas koloneve në "datën e dërgesës" me një periudhë një mujor
--version 1.0
do language plpgsql $$
declare 
rec_shipment_date RECORD ;
partition_name varchar;
index_name varchar;
current_year varchar ;
current_month varchar ;
begin_year varchar ;
begin_month varchar ;
next_year varchar ;
next_month varchar ;
first_flag boolean ;
i integer ;

begin

  RAISE NOTICE 'KRIJO TABELË TEMPORARE PËR DATËN E DËRGESËS';
  CREATE TEMP TABLE tmp_shipment_date as select distinct "SHIPMENT_DATE" from shipment order by "SHIPMENT_DATE" ;


  RAISE NOTICE 'FSHIJ TABELËN data';
  drop table data cascade ;


  RAISE NOTICE 'KRIJO TABELËN E PARTITIONUAR data';
  
  CREATE TABLE public.data
  (
    "RUN_ID" integer,
    "LASERMARK" character varying(20) COLLATE pg_catalog."default" NOT NULL,
    "LOTID" character varying(80) COLLATE pg_catalog."default",
    "SHIPMENT_ID" integer NOT NULL,
    "PARAMETER_ID" integer NOT NULL,
    "INTERNAL_VALUE" character varying(75) COLLATE pg_catalog."default",
    "REPORTED_VALUE" character varying(75) COLLATE pg_catalog."default",
    "LOWER_SPEC_LIMIT" numeric,
    "UPPER_SPEC_LIMIT" numeric , 
    "SHIPMENT_DATE" timestamp without time zone
  )
  PARTITION BY RANGE ("SHIPMENT_DATE")
  WITH (
    OIDS = FALSE
  )
  TABLESPACE pg_default ;


  RAISE NOTICE 'KRIJO PARTICIONET PËR TABELËN data';

  current_year:='0';
  current_month:='0';

  begin_year := '0' ;
  begin_month := '0'  ;
  next_year := '0' ;
  next_month := '0'  ;
  i := 1;

  FOR rec_shipment_date IN SELECT * FROM tmp_shipment_date LOOP
      
      RAISE NOTICE 'SHIPMENT_DATE=%',rec_shipment_date."SHIPMENT_DATE";
      
      current_year := date_part('year' ,rec_shipment_date."SHIPMENT_DATE");
      current_month := date_part('month' ,rec_shipment_date."SHIPMENT_DATE") ; 

      --Inicijalizo kufijtë
      IF   begin_year = '0' THEN
       RAISE NOTICE '***Inicijalizo kufijtë';
       first_flag := true ; --flag për herën e parë
       begin_year := current_year ;
       begin_month := current_month ;   
   
        IF current_month = '12' THEN
          next_year := date_part('year' ,rec_shipment_date."SHIPMENT_DATE" + interval '1 year') ;
        ELSE
          next_year := current_year ;
        END IF;
     
       next_month := date_part('month' ,rec_shipment_date."SHIPMENT_DATE" + interval '1 month') ;

      END IF;

--      RAISE NOTICE 'current_year=% , current_month=% ',current_year,current_month;
--      RAISE NOTICE 'begin_year=% , begin_month=% ',begin_year,begin_month;
--      RAISE NOTICE 'next_year=% , next_month=% ',next_year,next_month;

      -- Kontrollo datën e tanishme brenda kufijve, JO për herën e parë

      RAISE NOTICE 'Të dhënat aktuale = %',to_char( to_date( current_year||'.'||current_month, 'YYYY.MM'), 'YYYY.MM');
      RAISE NOTICE 'Të dhënat fillestare = %',to_char( to_date( begin_year||'.'||begin_month, 'YYYY.MM'), 'YYYY.MM');
      RAISE NOTICE 'Të dhënat e ardhshme = %',to_char( to_date( next_year||'.'||next_month, 'YYYY.MM'), 'YYYY.MM');

      IF to_date( current_year||'.'||current_month, 'YYYY.MM') >= to_date( begin_year||'.'||begin_month, 'YYYY.MM') AND 
         to_date( current_year||'.'||current_month, 'YYYY.MM') < to_date( next_year||'.'||next_month, 'YYYY.MM') AND 
         NOT first_flag 
      THEN
         RAISE NOTICE '***VAZHDO';
         CONTINUE ; 
      ELSE
       --Kufij të rinj vetëm për herën e dytë e më tepër 
       RAISE NOTICE '***KUFIJ TË RINJ';
       begin_year := current_year ;
       begin_month := current_month ;   
   
        IF current_month = '12' THEN
          next_year := date_part('year' ,rec_shipment_date."SHIPMENT_DATE" + interval '1 year') ;
        ELSE
          next_year := current_year ;
        END IF;
     
       next_month := date_part('month' ,rec_shipment_date."SHIPMENT_DATE" + interval '1 month') ;


      END IF;      

      IF to_number(current_month,'99') < 10 THEN
        current_month := '0'||current_month ; 
      END IF ;

      IF to_number(begin_month,'99') < 10 THEN
        begin_month := '0'||begin_month ; 
      END IF ;

      IF to_number(next_month,'99') < 10 THEN
        next_month := '0'||next_month ; 
      END IF ;

      RAISE NOTICE 'current_year=% , current_month=% ',current_year,current_month;
      RAISE NOTICE 'begin_year=% , begin_month=% ',begin_year,begin_month;
      RAISE NOTICE 'next_year=% , next_month=% ',next_year,next_month;

      partition_name := 'data_'||begin_year||begin_month||'01_'||next_year||next_month||'01'  ;

      RAISE NOTICE 'NUMRI I PARTICIONIT % , EMRI I TABELËS =%',i , partition_name;
      
      EXECUTE format('CREATE TABLE ' || quote_ident(partition_name) || ' PARTITION OF data FOR VALUES FROM ( %L ) TO ( %L )  ' , begin_year||'-'||begin_month||'-01' , next_year||'-'||next_month||'-01'  ) ; 

      index_name := partition_name||'_shipment_id_parameter_id_idx';
      RAISE NOTICE 'EMRI I INDEXIT =%',index_name;
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_ID", "PARAMETER_ID") TABLESPACE pg_default ' ) ; 

      index_name := partition_name||'_lasermark_idx';
      RAISE NOTICE 'EMRI I INDEXIT =%',index_name;
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("LASERMARK" COLLATE pg_catalog."default") TABLESPACE pg_default ' ) ; 

      index_name := partition_name||'_shipment_id_idx';
      RAISE NOTICE 'EMRI I INDEXIT =%',index_name;
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_ID") TABLESPACE pg_default ' ) ; 

      index_name := partition_name||'_parameter_id_idx';
      RAISE NOTICE 'EMRI I INDEXIT =%',index_name;
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("PARAMETER_ID") TABLESPACE pg_default ' ) ; 

      index_name := partition_name||'_shipment_date_idx';
      RAISE NOTICE 'EMRI I INDEXIT =%',index_name;
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_DATE") TABLESPACE pg_default ' ) ; 

      --Fshij flagun e herës së parë
      first_flag := false ;

  END LOOP;
end
$$;

Po ngarkohet dump-i i krijuar në hapin 3.

pg_restore -h host -u user -d database --data-only --format=c --table=data --verbose  data.dmp > data_restore.log 2>&1

Krijojmë një seksion të veçantë për të dhënat e vjetra

---------------------------------------------------
--create_partition_for_old_dates.sql
--krijoni seksione për ruajtjen e datave të vjetra 
--version 1.0
do language plpgsql $$
declare 
rec_shipment_date RECORD ;
partition_name varchar;
index_name varchar;

begin

      SELECT min("SHIPMENT_DATE") AS min_date INTO rec_shipment_date from data ;

      RAISE NOTICE 'Data e vjetër është %',rec_shipment_date.min_date ;

      partition_name := 'data_old_dates'  ;

      RAISE NOTICE 'EMRI I SEKSSIONIT ËSHTË %',partition_name;

      EXECUTE format('KRIJO TABELËN ' || quote_ident(partition_name) || ' PARTITION OF data FOR VALUES FROM ( %L ) TO ( %L )  ' , '1900-01-01' , 
              to_char( rec_shipment_date.min_date,'YYYY')||'-'||to_char(rec_shipment_date.min_date,'MM')||'-01'  ) ; 

      index_name := partition_name||'_shipment_id_parameter_id_idx';
      EXECUTE format('KRIJO INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_ID", "PARAMETER_ID") TABLESPACE pg_default ' ) ; 

      index_name := partition_name||'_lasermark_idx';
      EXECUTE format('KRIJO INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("LASERMARK" COLLATE pg_catalog."default") TABLESPACE pg_default ' ) ; 

      index_name := partition_name||'_shipment_id_idx';
      EXECUTE format('KRIJO INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_ID") TABLESPACE pg_default ' ) ; 

      index_name := partition_name||'_parameter_id_idx';
      EXECUTE format('KRIJO INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("PARAMETER_ID") TABLESPACE pg_default ' ) ; 

      index_name := partition_name||'_shipment_date_idx';
      EXECUTE format('KRIJO INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_DATE") TABLESPACE pg_default ' ) ; 

end
$$;

Rezultatet përfundimtare:

Ishte
Kosto: 502 997.55
Koha e ekzekutimit: 505 sekonda.

Nisi
Kosto: 68 533.70
Koha e ekzekutimit: 69 sekonda

RrallĂ«, shumĂ« rrallĂ«. Dhe duke marrĂ« parasysh se gjatĂ« rrugĂ«s arritĂ«m tĂ« mĂ«sojmĂ« pak nga mekanizmi i seksionimit nĂ« PostgreSQL 10 — NjĂ« rezultat i shkĂ«lqyer.

Një shpërndarje lirikë

Por a mund tĂ« bĂ«het akoma mĂ« mirĂ« — PO, MUND!PĂ«r kĂ«tĂ« duhen pĂ«rdorur MATERIALIZED VIEW.
CREATE MATERIALIZED VIEW LASERMARK_VIEW

CREATE MATERIALIZED VIEW LASERMARK_VIEW 
AS
SELECT w."LASERMARK" , MAX(s."SHIPMENT_DATE") AS "SHIPMENT_DATE"
FROM shipment s INNER JOIN data w ON s."SHIPMENT_ID" = w."SHIPMENT_ID" 
GROUP BY w."LASERMARK" ;

CREATE INDEX lasermark_vw_shipment_date_ind on lasermark_view USING btree ("SHIPMENT_DATE") TABLESPACE pg_default;
analyze lasermark_view ;

Përsëri shkruajmë kërkesën:
Kërkesa me përdorimin e materialized view

SELECT
            p."PARAMETER_ID" as  parameter_id,
            pc."PC_NAME" AS pc_name,
            pc."CUSTOMER_PARTNUMBER" AS customer_partnumber,
            w."LASERMARK" AS lasermark,
            w."LOTID" AS lotid,
            w."REPORTED_VALUE" AS reported_value,
            w."LOWER_SPEC_LIMIT" AS lower_spec_limit,
            w."UPPER_SPEC_LIMIT" AS upper_spec_limit,
            p."TYPE_CALCUL" AS type_calcul,
            s."SHIPMENT_NAME" AS shipment_name,
            s."SHIPMENT_DATE" AS shipment_date,
            extract(year from s."SHIPMENT_DATE") AS year,
            extract(month from s."SHIPMENT_DATE") as month,
            s."REPORT_NAME" AS report_name,
            p."STC_NAME" AS STC_name,
            p."CUSTOMERPARAM_NAME" AS customerparam_name
        FROM data w INNER JOIN shipment s ON s."SHIPMENT_ID" = w."SHIPMENT_ID"
             INNER JOIN parameters p ON p."PARAMETER_ID" = w."PARAMETER_ID"
             INNER JOIN shipment_pc sp ON s."SHIPMENT_ID" = sp."SHIPMENT_ID"
             INNER JOIN pc pc ON pc."PC_ID" = sp."PC_ID"
             INNER JOIN LASERMARK_VIEW md ON md."SHIPMENT_DATE" = s."SHIPMENT_DATE" AND md."LASERMARK" = w."LASERMARK"
        WHERE 
              s."SHIPMENT_DATE" >= '2018-07-01' AND s."SHIPMENT_DATE" <= '2018-09-30';

Dhe kështu merrni një tjetër rezultat:
Ishte
Kosto: 502 997.55
Koha e ekzekutimit: 505 sekonda

Nisi
Kosto: 42 481.16
Koha e ekzekutimit: 43 sekonda.

Megjithatë, kjo rezultat që premton aq shumë është i mashtuar, sepse prezantimet duhet të rifreskohen. Pra, koha përfundimtare për marrjen e të dhënave nuk ndihmon shumë. Por për eksperimente është mjaft interesante.

Në të vërtetë, siç doli, faleminderit përsëri asmm dhe Habr! - kërkesa mund të përmirësohet më tej.

Pasthënie

Pra, klienti është i kënaqur. Dhe nevojitet të shfrytëzojmë situatën.

DetyrĂ« e re: ÇfarĂ« mund tĂ« krijojmĂ« pĂ«r tĂ« thelluar dhe zgjeruar?

Dhe kĂ«tu kujtojmĂ« — djem, nuk kemi monitorimin e bazave tona tĂ« tĂ« dhĂ«nave PostgreSQL.

Me dorë në zemër, ka një monitorim në formën e Cloud Watch në AWS. Por çfarë dobi na sjell ky monitorim për DBA? Në thelb, pothuajse asgjë.

Nëse shfaqet mundësia për të bërë diçka të dobishme dhe interesante për veten, nuk duhet ta humbim këtë mundësi...
SE

Happy Party ose disa rreshta kujtimesh për njohjen me seksionimin në PostgreSQL10

Kështu erdhëm në më të rëndësishmen:

3 Dhjetor 2018.
Marrja e vendimit për fillimin e punëve për hulumtimin e mundësive aktuale të monitorimit të performancës së kërkesave PostgreSQL.

Por kjo është një histori krejt tjetër.

Vazhdimi, vijon


Burimi: habr.com

Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster