Happy Party vagy néhány sor-emlék a PostgreSQL10 szekciózásának megismeréséről

Előszó vagy hogyan született a szekcionálás ötlete

A történet itt kezdődik: Emlékszel, hogyan kezdődött minden? Minden először és újra történt. Miután szinte minden forrás kimerült a lekérdezés optimalizálásához, felmerült a kérdés - mi legyen tovább? Így jött a szekcionálás ötlete.

Happy Party vagy néhány sor-emlék a PostgreSQL10 szekciózásának megismeréséről

Lírai kitérő:
Pontosan 'abban az időszakban', mert ahogy kiderült, voltak kihasználatlan optimalizálási tartalékok. Köszönöm asmm és a Habrnak!

Tehát, hogyan tehetjük boldogabbá az ügyfelet, miközben fejlesztjük a saját készségeinket?

Ha mindent a legegyszerűbbre leegyszerűsítünk,, akkor a drámai javítás néhány útja a adatbázis teljesítményében csupán kettő:
1) Extenzív megközelítés - erőforrások növelése, beállítások módosítása;
2) Intenzív megközelítés - lekérdezések optimalizálása

Mivel, ismétlem, abban az időszakban már nem volt világos, mit lehetne még megváltoztatni a lekérdezés gyorsításához, a megoldás az lett, hogy - táblázatok dizájnjának megváltoztatása.

Tehát - felmerül a fő kérdés - mit és hogyan fogunk megváltoztatni?

Kezdőfeltételek

Először is, egy ilyen ERD-nk van (ábrázolva önkényesen - leegyszerűsítve):
Happy Party vagy néhány sor-emlék a PostgreSQL10 szekciózásának megismeréséről
Főbb jellemzők:

  1. a 'sok a sokhoz' kapcsolatok
  2. a táblázat már potenciális szekcionálási kulccsal rendelkezik

Eredeti lekérdezés:

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' ;

A végrehajtás eredménye a tesztadatbázison:
Költség : 502 997.55
Végrehajtási idő: 505 másodperc.

Mit látunk? Egy szokásos lekérdezés, időbeli szeletekre.
Tehát végezzünk el egy egyszerű logikai következtetést: ha van egy időszakos minta, akkor segít nekünk? Helyes — a szegmentálás.

Mit szegmentáljunk?

Első pillantásra a választás egyértelmű — a "shipment" táblázat deklaratív szegmentálása a "SHIPMENT_DATE" kulcs szerint (gyorsan előreugorva — a végén a produkció kicsit más lett).

Hogyan szegmentáljunk?

Ez a kérdés sem túl nehéz. Szerencsére a PostgreSQL 10-ben most már van egy emberbarát szegmentálási mechanizmus.
Tehát:

  1. Mentjük az eredeti táblázat dump-ját — pg_dump source_table
  2. Töröljük az eredeti táblázatot — drop table source_table
  3. Hozzuk létre a szülő táblázatot a tartomány szerinti szegmentálással — create table source_table
  4. Hozzuk létre a szegmenseket — create table source_table, create index
  5. Importáljuk a dump-ot, amit az 1. lépésben készítettünk — pg_restore

Szegmentálási szkriptek

Az egyszerűség és kényelem kedvéért a 2., 3. és 4. lépéseket egy szkriptbe összevontuk.

Tehát:
Mentjük az eredeti táblázat dump-ját

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

Töröljük az eredeti táblázatot + Hozzuk létre a szülő táblázatot a tartomány szerinti szegmentálással + Hozzuk létre a szegmenseket

--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 'CREATE TEMPORARY TABLE FOR SHIPMENT_DATE';
  CREATE TEMP TABLE tmp_shipment_date as select distinct "SHIPMENT_DATE" from shipment order by "SHIPMENT_DATE" ;

  RAISE NOTICE 'DROP TABLE shipment';
  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 'CREATE PARTITIONS FOR TABLE shipment';

  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
       --NEW borders only for second and after time 
       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 'INDEX NAME =%',index_name;
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_ID") TABLESPACE pg_default ' ) ; 

      --Drop first time flag
      first_flag := false ;
   
  END LOOP;

end
$$;

Importáljuk a dump-ot

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

Ellenőrizzük a szekcionálás eredményeit

Mit is eredményezett mindez? A végrehajtási terv teljes szövege hosszú és unalmas, így nyugodtan lehet az összegző számokra korlátozódni.

Volt

Költség: 502 997.55
Végrehajtási idő: 505 másodperc.

Lett

Költség: 77 872.36
Végrehajtási idő: 79 másodperc.

Teljesen jó eredmény. Csökkentettük a költségeket és a végrehajtási időt. Így a particionálás használata hozza a várt hatást, összességében meglepetések nélkül.

Megörvendeztetni az ügyfelet

A tesztelési eredményeket az ügyfél számára bemutatták. A megismerés után kicsit váratlan ítéletet hozott: „Remek, particionálja a 'data' táblát.”

Igen, de mi egészen másik táblát, a 'shipment' táblát vizsgáltuk, a 'data' táblának nincsen 'SHIPMENT_DATE' mezője.

Nem probléma, adjon hozzá, változtasson. A lényeg, hogy az ügyfél elégedett legyen a végeredménnyel, a megvalósítás részletei nem annyira fontosak.

Particionáljuk az alap 'data' táblát

Alapvetően különösebb nehézségek nem merültek fel. Bár a particionálási algoritmus természetesen kissé megváltozott.

Hozzáadjuk a 'SHIPMENT_DATE' oszlopot a 'data' táblához

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

Kitöltjük a 'SHIPMENT_DATE' oszlop értékeit a 'data' táblában az azonos nevű oszlop értékeivel a 'shipment' táblából

-----------------------------
--update_data.sql
--frissítés a módosított 'data' táblához a 'shipment' táblából a 'shipment_data' értékeivel
--verzió 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 'Összesen %',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 'sor szám = % , összesen %',row_count,total_rows;
  END LOOP;

end
$$;

Mentjük a 'data' tábla dump-ját

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

Újra létrehozzuk a particionált 'data' táblát

--create_partition_data.sql
--partíciók létrehozása a "wafer data" táblához a "shipment_data" időszakos oszlop alapján, egy hónapos időtartammal
--verzió 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 'IDEIGLENES TÁBLA LÉTREHOZÁSA A SZÁLLÍTÁSI DÁTUMHOZ';
  CREATE TEMP TABLE tmp_shipment_date as select distinct "SHIPMENT_DATE" from shipment order by "SHIPMENT_DATE" ;


  RAISE NOTICE 'ADAT TÁBLA TÖRLÉSE';
  drop table data cascade ;


  RAISE NOTICE 'PARTÍCIONÁLT ADAT TÁBLA LÉTREHOZÁSA';
  
  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 'PARTÍCIONÁK LÉTREHOZÁSA A DATA TÁBLÁHOZ';

  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") ; 

      --Határok inicializálása
      IF   begin_year = '0' THEN
       RAISE NOTICE '***Határok inicializálása';
       first_flag := true ; --első alkalom jelző
       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;

      -- Ellenőrizze az aktuális dátumot a határok között NEM az első alkalomra

      RAISE NOTICE 'Aktuális adat = %',to_char( to_date( current_year||'.'||current_month, 'YYYY.MM'), 'YYYY.MM');
      RAISE NOTICE 'Kezdő adat = %',to_char( to_date( begin_year||'.'||begin_month, 'YYYY.MM'), 'YYYY.MM');
      RAISE NOTICE 'Következő adat = %',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 '***FOLYTATÁS';
         CONTINUE ; 
      ELSE
       --Új határok csak másodszor és az után 
       RAISE NOTICE '***ÚJ HATÁROK';
       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 'PARTÍCIÓ SZÁMA % , TÁBLA NEVE =%',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 'INDEX NÉV =%',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 'INDEX NÉV =%',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 'INDEX NÉV =%',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 'INDEX NÉV =%',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 'INDEX NÉV =%',index_name;
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_DATE") TABLESPACE pg_default ' ) ; 

      --Törölje az első alkalom jelzőt
      first_flag := false ;

  END LOOP;
end
$$;

Betöltjük a 3. lépésben létrehozott dump fájlt.

pg_restore -h host -u felhasználó -d adatbázis --data-only --format=c --table=data --verbose data.dmp > data_restore.log 2>&1

Külön szekciót hozunk létre a régi adatok számára

---------------------------------------------------
--create_partition_for_old_dates.sql
--partíciók létrehozása a régi dátumok tárolásához 
--verzió 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 'Régi dátum: %', rec_shipment_date.min_date ;

      partition_name := 'data_old_dates'  ;

      RAISE NOTICE 'PARTÍCÓ NEVE: %', partition_name;

      EXECUTE format('CREATE TABLE ' || 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('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';
      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';
      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';
      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';
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_DATE") TABLESPACE pg_default ' ) ; 

end
$$;

Végeredmények:

Volt
Költség: 502 997.55
Végrehajtási idő: 505 másodperc.

Lett
Költség: 68 533.70
Végrehajtási idő: 69 másodperc

Megfelelő, igazán megfelelő. Figyelembe véve, hogy útközben sikerült viszonylag elsajátítani a PostgreSQL 10 szekcionáló mechanizmusát - Kiváló eredmény.

Lírai kitérő

Lehetne még jobb - IGEN, LEHETSÉGES!Ehhez MATERIALIZED VIEW-t kell használni.
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 ;

Ismét átfogalmazzuk a lekérdezést:
Lekérdezés materialized view használatával

VÁLASZ
            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';

És kapunk egy újabb eredményt:
Volt
Költség: 502 997.55
Végrehajtási idő: 505 másodperc

Lett
Költség: 42 481.16
Végrehajtási idő: 43 másodperc.

Bár nyilvánvalóan, egy ilyen ígéretes eredmény megtévesztő lehet, a megjelenéseket frissíteni kell. Tehát az adatok megszerzésének végső ideje nem sokat fog segíteni. De kísérletként mindenképpen érdekes.

Valójában, ahogy kiderült, még egyszer köszönöm asmm és a Habrunak !- a lekérdezés még jobbá tehető.

Utószó

Tehát az ügyfél elégedett. És a készülék helyének ismeretére. Ha kihasználni a helyzetet.

Új feladat: Mit lehetne kitalálni, hogy mélyebb és szélesebb legyen?

És itt jut eszünkbe — srácok, de hiszen nincs monitorozásunk a PostgreSQL adatbázisainkról.

A szívünkre tesszük a kezünket, van valamiféle monitorozás a Cloud Watch-on az AWS-en. De mi haszna van ebből a monitorozásból a DBA számára? Valójában szinte semmi.

Ha lehetőség nyílt egy hasznos és érdekes dolog létrehozására magunk számára, nem lehet elhagyni egy ilyen esélyt ...
MERT

Happy Party vagy néhány sor-emlék a PostgreSQL10 szekciózásának megismeréséről

Így jutottunk el a legérdekesebbhez:

2018. december 3.
Döntés a PostgreSQL lekérdezések teljesítményének monitorozásának lehetőségeinek kutatásáról.

De ez már egy teljesen másik történet.

Folytatás következik…

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster