Happy Party vĂ”i lĂŒhike mĂ€lestus sektsioneerimisest PostgreSQL10-s

EessÔna vÔi kuidas tekkis ideoloogia sektsioneerimise kohta

Loo algus siin: Kas sa mĂ€letad, kuidas kĂ”ik algas. KĂ”ik oli esmakordne ja uuesti. P pĂ€rast seda, kui peaaegu kĂ”ik ressursid pĂ€ringu optimeerimiseks olid toona vĂ€ljapeetud, tuli kĂŒsimus — mis edasi? Nii tekkis idee sektsioneerimisest.

Happy Party vĂ”i lĂŒhike mĂ€lestus sektsioneerimisest PostgreSQL10-s

LĂŒhiĂŒlevaade:
Just 'toona', kuna nagu selgus, olid olematud optimeerimise ressursid. AitÀh asmm ja Habrule!

Nii, kuidas veel vÔiks klienti Ônnelikuks teha, ja samal ajal oma oskusi parandada?

Kui kÔik vÔimalikult lihtsaks teha, siis on kaks peamist teed, kuidas midagi radikaalselt parandada andmebaasi jÔudluses:
1) Ekstensiivne tee — suurendame ressursse, muudame konfiguratsiooni;
2) Intensiivne tee — pĂ€ringute optimeerimine

Kuna, kordustan, toona ei olnud selge, mida veel pĂ€ringus muuta kiirusel, valiti tee — tabelite disaini muutmine.

Nii — tĂ”useb peamine kĂŒsimus — mida ja kuidas me muudame?

Algtingimused

Esiteks, on olemas selline ERD (nÀidatud tinglikult-lihtsustatud):
Happy Party vĂ”i lĂŒhike mĂ€lestus sektsioneerimisest PostgreSQL10-s
PÔhiomadused:

  1. suhted "palju paljude" vahel
  2. tabelil on juba potentsiaalne sektsioneerimise vÔti

Algne pÀring:

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

Testandme tulemuste tÀitmine testandmebaasis:
Maksumus : 502 997.55
TĂ€ideviimise aeg: 505 sekundit.

Mida me nÀeme? Tavaline pÀring ajavahemiku jÀrgi.
Teeme lihtsa loogilise oletuse: kui on valik ajalisest lĂ”igust, kas see aitab meid? Õige — sektsioneerimine.

Mida sektsioneerida?

Esmapilgul tundub valik ilmne — deklaratiivne sektsioneerimine tabeli „shipment” jĂ€rgi vĂ”tme „SHIPMENT_DATE” jĂ€rgi (liialt ette ruttamata — lĂ”puks tuli tootmises vĂ€lja veidi teistmoodi).

Kuidas sektsioneerida?

See kĂŒsimus ei ole samuti liiga keeruline. Õnneks on PostgreSQL 10-s nĂŒĂŒd inimlik sektsioneerimise mehhanism.
Nii:

  1. Salvestame algse tabeli dump'i — pg_dump source_table
  2. Kustutame algse tabeli — drop table source_table
  3. Loome vanemtabeli, sektsioneerides selle vahemiku jĂ€rgi — create table source_table
  4. Loome sektsioonid — create table source_table, create index
  5. Importime dump'i, mis loodi 1. sammus — pg_restore

Sektsioneerimise skriptid

Lihtsuse ja mugavuse huvides on 2, 3, 4. sammud koondatud ĂŒhte skripti.

Nii:
Salvestame algse tabeli dump'i

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

Kustutame algse tabeli + Loome vanemtabeli, sektsioneerides selle vahemiku jÀrgi + Loome sektsioonid

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

  RAISE NOTICE 'KUSTUTA 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 'LOO PARTITSIOONID TABLE FOR 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
       --UUED piirded ainult teisel ja hiljem
       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 ' ) ; 

      --Kustuta esmakordne lipp
      first_flag := false ;
   
  END LOOP;

end
$$;

Impordime dump

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

Kontrollime sektsioneerimise tulemusi

Mida me siis tulemuseks saime? Plaani tÀisteksti tÀitmine on suur ja igav, seega saab piirduda lÔpnumbritega.

See oli

Kulu: 502 997.55
TĂ€itev aeg: 505 sekundit.

Muutus

Kulu: 77 872.36
TĂ€itev aeg: 79 sekundit.

Kohati hea tulemus. VĂ€henes kulu ja tĂ€itmise aeg. Seega annab sektsioneerimise kasutamine oodatud efekti ja ĂŒldiselt — ilma ĂŒllatusteta.

Tellija rÔÔmustamine

Testimise tulemused esitati tellijale tutvumiseks. Ja pĂ€rast tutvumist anti vĂ€lja mitmeti ĂŒllatav otsus: "SuurepĂ€rane, sektsioneerige tabel 'data'."

Jah, aga me uurisime hoopis teist tabelit 'shipment', tabel 'data' ei sisalda vÀlja 'SHIPMENT_DATE'.

Ei ole probleemi, lisage ja muutke. Peaasi, et tellijat rahuldab see, mis tulemuseks saab, teostuse detailid ei ole vÀga olulised.

Sektsioneerime pÔhitaabelit 'data'

KokkuvÔttes ei tekkinud mingeid erilisi raskusi. Kuigi, sektsioneerimise algoritm on muidugi natuke muutunud.

Lisame veeru 'SHIPMENT_DATA' tabelisse 'data'

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

TÀidame veeru 'SHIPMENT_DATA' tabelis 'data' sama nimega veeru vÀÀrtustega tabelist 'shipment'

-----------------------------
--update_data.sql
--tÀiendamine muudetud tabeli "data" jaoks vÀÀrtustega tabelist "shipment_data"
--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 'Kokku %',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 'read arvu = % , kokku %',row_count,total_rows;
  END LOOP;

end
$$;

Salvestame tabeli 'data' dump'i

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

Loome sektsioneeritud tabeli 'data' uuesti

--create_partition_data.sql
--looge partitsioonid tabelile "wafer data" vahemiku veeru "shipment_data" alusel, mille kestus on ĂŒks kuu
--versioon 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 'LOO TEMPORARY TABLE SHIPMENT_DATE';
  CREATE TEMP TABLE tmp_shipment_date as select distinct "SHIPMENT_DATE" from shipment order by "SHIPMENT_DATE" ;


  RAISE NOTICE 'KUSTUTA TABLE data';
  drop table data cascade ;


  RAISE NOTICE 'LOO PARTITSIONEID TABELILE 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 'LOO PARTITSIOONEID TABELILE 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") ; 

      --Initsiaalne piir
      IF   begin_year = '0' THEN
       RAISE NOTICE '***Initsiaalne piir';
       first_flag := true ; --esmakordne lipp
       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;

      -- Kontrolli praegust kuupÀeva piirides mitte esmakordse jaoks

      RAISE NOTICE 'Praegune kuupÀev = %',to_char( to_date( current_year||'.'||current_month, 'YYYY.MM'), 'YYYY.MM');
      RAISE NOTICE 'AlguskuupÀev = %',to_char( to_date( begin_year||'.'||begin_month, 'YYYY.MM'), 'YYYY.MM');
      RAISE NOTICE 'JÀrgmine kuupÀev = %',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 '***JATKA';
         CONTINUE ; 
      ELSE
       --Uued piirid ainult teisel ja hilisemal korral 
       RAISE NOTICE '***UUED PIIRID';
       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 'PARTITSIOONI NUMBER % , TABELI NIME =%',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 'INDEXI NIMI =%',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 'INDEXI NIMI =%',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 'INDEXI NIMI =%',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 'INDEXI NIMI =%',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 'INDEXI NIMI =%',index_name;
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_DATE") TABLESPACE pg_default ' ) ; 

      --Kustuta esmakordne lipp
      first_flag := false ;

  END LOOP;
end
$$;

Laadime faile, mis loodi sammul 3.

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

Loome eraldi sektsiooni vanade andmete jaoks

---------------------------------------------------
--create_partition_for_old_dates.sql
--loome sektsioone vanade kuupÀevade hoidmiseks
--versioon 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 'Vana kuupÀev on %', rec_shipment_date.min_date ;

      partition_name := 'data_old_dates'  ;

      RAISE NOTICE 'SEKTSIOONI NIMI ON %', 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
$$;

LÔppjÀreldused:

See oli
Kulu: 502 997.55
TĂ€ideviimise aeg: 505 sekundit.

Muutus
Kulu: 68 533.70
TĂ€itev aeg: 69 sekundit

AuvÀÀrne, tĂ€iesti auvÀÀrne. Arvestades, et teel Ă”ppisime rohkem-vĂ”i vĂ€hem PostgreSQL 10 sektsioneerimise mehhanismi — SuurepĂ€rane tulemus.

LĂŒhiĂŒhendus

Kas saab veel paremini teha — JAH, SAAB!Selleks on vaja kasutada 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 ;

Kordame uuesti pÀringut:
PĂ€ring kasutades materialized view

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

Ja saame veel ĂŒhe kokkuvĂ”tte:
See oli
Kulu: 502 997.55
TĂ€ideviimise aeg: 505 sekundit

Muutus
Kulu: 42 481.16
TĂ€itev aeg: 43 sekundit.

Ehkki see nii palju lubav tulemus vÔib olla petlik, tuleb esitlusi vÀrskendada. Seega ei aita lÔplik andmete saamise aeg palju. Kuid eksperimendina on see igati huvitav.

Tegelikult, nagu selgus, veel kord aitÀh asmm ja Habrule!- pÀringu vÔib veel tÀiustada.

EessÔna

Nii et tellija on rahul. Ja vajalik kasutada olukorda.

Uus ĂŒlesanne: Mis vĂ”iks meil sellist vĂ€lja mĂ”elda, et sĂŒvendada ja laiendada?

Ja siin tuleb meelde – poisid, meil pole meie PostgreSQL andmebaaside jĂ€lgimist.

Asetades kĂ€e sĂŒdamele, on omad jĂ€lgimisvĂ”imalused AWS Cloud Watchis siiski olemas. Kuid kui palju kasu on sellest jĂ€lgimisest DBA-le? Üldiselt on seda praktiliselt ĂŒldse mitte.

Kui on vÔimalus teha endale kasulik ja huvitav, ei saa sellisest vÔimalusest loobuda 

SEST

Happy Party vĂ”i lĂŒhike mĂ€lestus sektsioneerimisest PostgreSQL10-s

Nii jÔudsime huvitavale teemale:

3. detsember 2018.
Otsus alustada töödega PostgreSQL pÀringute jÔudluse jÀlgimise vÔimaluste uurimiseks.

Aga see on juba hoopis muu lugu.

JĂ€tkub...

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster