Happy Party ืื• ื›ืžื” ืฉื•ืจื•ืช-ื–ื›ืจื•ื ื•ืช ืฉืœ ื”ื™ื›ืจื•ืช ืขื ืžื—ื™ืฆื•ืช ื‘-PostgreSQL10

ื”ืงื“ืžื” ืื• ืื™ืš ื ื•ืฆืจ ืจืขื™ื•ืŸ ื”ื—ืชืš

ื”ืกื™ืคื•ืจ ืžืชื—ื™ืœ ื›ืืŸ: ืืชื” ื–ื•ื›ืจ ืื™ืš ื”ื›ืœ ื”ืชื—ื™ืœ. ื”ื›ืœ ื”ื™ื” ื‘ืคืขื ื”ืจืืฉื•ื ื” ื•ืฉื•ื‘. ืœืื—ืจ ืฉื›ืžืขื˜ ื›ืœ ื”ืžืฉืื‘ื™ื ืœื™ื™ืขื•ืœ ื”ื‘ืงืฉื”, ืื–, ืžื•ืฆื•, ืขืœืชื” ื”ืฉืืœื” - ืžื” ื”ืœืื”? ื›ืš ืขืœื” ืจืขื™ื•ืŸ ื”ื—ืœื•ืงื”.

Happy Party ืื• ื›ืžื” ืฉื•ืจื•ืช-ื–ื›ืจื•ื ื•ืช ืฉืœ ื”ื™ื›ืจื•ืช ืขื ืžื—ื™ืฆื•ืช ื‘-PostgreSQL10

ืกื˜ื™ื™ื” ืœื™ืจื™ืช:
ื“ื•ื•ืงื 'ื‘ืื•ืชื• ืจื’ืข', ื›ื™ ื›ืคื™ ืฉื”ืชื‘ืจืจ, ื”ื™ื• ืขืชื•ื“ื•ืช ืื•ืคื˜ื™ืžื™ื–ืฆื™ื” ืฉืœื ื ื•ืฆืœื•. ืชื•ื“ื” asmm ื•ื”ื‘ืจื•!

ืื– ืื™ืš ืขื•ื“ ืชื•ื›ืœื• ืœืฉืžื— ืืช ื”ืœืงื•ื—, ื•ื‘ืžืงื‘ื™ืœ ืœืฉืคืจ ืืช ื”ื›ื™ืฉื•ืจื™ื ืฉืœื›ื?

ื›ื“ื™ ืœืคืฉื˜ ื”ื›ืœ ื›ืžื” ืฉืืคืฉืจ, ืื– ื™ืฉ ืจืง ืฉืชื™ ื“ืจื›ื™ื ืœืฉืคืจ ื‘ืื•ืคืŸ ืงื™ืฆื•ื ื™ ืžืฉื”ื• ื‘ื‘ื™ืฆื•ืขื™ื ืฉืœ ืžืกื“ ื”ื ืชื•ื ื™ื:
1) ื ืชื™ื‘ ื ืจื—ื‘ - ืื ื• ืžื’ื“ื™ืœื™ื ืžืฉืื‘ื™ื, ืžืฉื ื™ื ืืช ื”ืชืฆื•ืจื”;
2) ื ืชื™ื‘ ืื™ื ื˜ื ืกื™ื‘ื™ - ืื•ืคื˜ื™ืžื™ื–ืฆื™ื” ืฉืœ ืฉืื™ืœืชื•ืช

ืžืื—ืจ, ืื ื™ ื—ื•ื–ืจ ื•ืื•ืžืจ, ื‘ืื•ืชื” ืชืงื•ืคื” ื›ื‘ืจ ืœื ื”ื™ื” ื‘ืจื•ืจ ืžื” ืขื•ื“ ืœืฉื ื•ืช ื‘ื‘ืงืฉื” ืœื”ืื™ืฅ, ื ื‘ื—ืจื” ื”ื“ืจืš - ืฉื™ื ื•ื™ื™ื ื‘ืขื™ืฆื•ื‘ ื”ืฉื•ืœื—ืŸ.

ืื–, ื ืฉืืœืช ื”ืฉืืœื” ื”ืขื™ืงืจื™ืช: ืžื” ื•ืื™ืš ื ืฉื ื”?

ืชื ืื™ื ื”ืชื—ืœืชื™ื™ื

ืจืืฉื™ืช, ื™ืฉ ืืช ื”-ERD ื”ื–ื” (ืžื•ืฆื’ ื‘ืฆื•ืจื” ืคืฉื•ื˜ื” ืขืœ ืชื ืื™):
Happy Party ืื• ื›ืžื” ืฉื•ืจื•ืช-ื–ื›ืจื•ื ื•ืช ืฉืœ ื”ื™ื›ืจื•ืช ืขื ืžื—ื™ืฆื•ืช ื‘-PostgreSQL10
ืชื›ื•ื ื•ืช ืขื™ืงืจื™ื•ืช:

  1. ืžืขืจื›ื•ืช ื™ื—ืกื™ื ืจื‘ื•ืช ืœืจื‘ื™ื
  2. ืœื˜ื‘ืœื” ื›ื‘ืจ ื™ืฉ ืžืคืชื— ืžื—ื™ืฆื” ืคื•ื˜ื ืฆื™ืืœื™

ื‘ืงืฉื” ืžืงื•ืจื™ืช:

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

ืชื•ืฆืื•ืช ื‘ื™ืฆื•ืข ื‘ืžืกื“ ื”ื ืชื•ื ื™ื ืฉืœ ื”ื‘ื“ื™ืงื”:
ืขืœื•ืช : 502 997.55
ื–ืžืŸ ื‘ื™ืฆื•ืข: 505 ืฉื ื™ื•ืช.

ืžื” ืื ื—ื ื• ืจื•ืื™ื? ื‘ืงืฉื” ืงื‘ื•ืขื”, ื”ืžื‘ื•ืกืกืช ืขืœ ืคืจื•ืกืช ื–ืžืŸ.
ื‘ื•ืื• ื ื ื™ื— ืืช ื”ื”ื ื—ื” ื”ืœื•ื’ื™ืช ื”ืคืฉื•ื˜ื” ื‘ื™ื•ืชืจ: ืื ื™ืฉ ื“ื•ื’ืžื” ืฉืœ ืคืจื•ืกืช ื–ืžืŸ, ื”ืื ื–ื” ื™ืขื–ื•ืจ ืœื ื•? ื ื›ื•ืŸ - ืžื—ื™ืฆื”.

ืžื” ืœื—ืœืง?

ื‘ืžื‘ื˜ ืจืืฉื•ืŸ, ื”ื‘ื—ื™ืจื” ื‘ืจื•ืจื” - ื—ืœื•ืงื” ื”ืฆื”ืจืชื™ืช ืฉืœ ื˜ื‘ืœืช "ืžืฉืœื•ื—" ื‘ืืžืฆืขื•ืช ืžืงืฉ "SHIPMENT_DATE" (ืœืงืคื•ืฅ ื™ื•ืชืจ ืžื“ื™ ืงื“ื™ืžื” - ื‘ืกื•ืคื• ืฉืœ ื“ื‘ืจ ื–ื” ื™ืฆื ืงืฆืช ืœื ื‘ืกื“ืจ ื‘ื”ืคืงื”).

ืื™ืš ืžื—ืœืงื™ื?

ื”ืฉืืœื” ื”ื–ื• ื’ื ืœื ืงืฉื” ืžื“ื™. ืœืžืจื‘ื” ื”ืžื–ืœ, ื‘-PostgreSQL 10, ืงื™ื™ื ื›ืขืช ืžื ื’ื ื•ืŸ ื—ืœื•ืงื” ืื ื•ืฉื™.
ืื–:

  1. ืฉืžื•ืจ dump ืฉืœ ื˜ื‘ืœืช ื”ืžืงื•ืจ - pg_dump source_table
  2. ืžื—ืง ืืช ื”ื˜ื‘ืœื” ื”ืžืงื•ืจื™ืช - ืฉื—ืจืจ ืืช ื”ื˜ื‘ืœื” source_table
  3. ืฆื•ืจ ื˜ื‘ืœืช ืื‘ ืขื ื—ืœื•ืงืช ื˜ื•ื•ื— - ืฆื•ืจ ื˜ื‘ืœื” source_table
  4. ืฆื•ืจ ืงื˜ืขื™ื - ืฆื•ืจ ื˜ื‘ืœื” source_table, ืฆื•ืจ ืื™ื ื“ืงืก
  5. ื™ื™ื‘ื ืืช ื”-dump ืฉื ื•ืฆืจ ื‘ืฉืœื‘ 1 - pg_restore

ืกืงืจื™ืคื˜ื™ื ืœืžื—ื™ืฆื•ืช

ืœืžืขืŸ ื”ืคืฉื˜ื•ืช ื•ื”ื ื•ื—ื•ืช, ืฉืœื‘ื™ื 2,3,4 ืฉื•ืœื‘ื• ืœืกืงืจื™ืคื˜ ืื—ื“.

ืื–:
ืฉืžื•ืจ dump ืฉืœ ื˜ื‘ืœืช ื”ืžืงื•ืจ

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

ืžื—ืง ืืช ื˜ื‘ืœืช ื”ืžืงื•ืจ + ืฆื•ืจ ื˜ื‘ืœืช ืื‘ ืขื ื—ืœื•ืงืช ื˜ื•ื•ื— + ืฆื•ืจ ืžื—ื™ืฆื•ืช

--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') < 10 THEN
        current_month := '0'||current_month ; 
      END IF ;

      --Init borders
      IF   begin_year = '0' THEN
       first_flag := true ; --first time flag
       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;

      -- Check current date into borders NOT for First time
      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
         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
$$;

ื™ื™ื‘ื•ื โ€‹โ€‹ื”ืžื–ื‘ืœื”

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

ื‘ื“ื™ืงืช ืชื•ืฆืื•ืช ื”ื—ืœื•ืงื”

ืžื” ื™ืฉ ืœื ื• ื›ืชื•ืฆืื” ืžื›ืš? ื”ื˜ืงืกื˜ ื”ืžืœื ืฉืœ ืชื•ื›ื ื™ืช ื”ื‘ื™ืฆื•ืข ื”ื•ื ื’ื“ื•ืœ ื•ืžืฉืขืžื, ืื– ื‘ื”ื—ืœื˜ ืืคืฉืจื™ ืœื”ื’ื‘ื™ืœ ืืช ืขืฆืžืš ืœืžืกืคืจื™ื ื”ืกื•ืคื™ื™ื.

ื”ื™ื”

ืขืœื•ืช: 502 997.55
ื–ืžืŸ ื‘ื™ืฆื•ืข: 505 ืฉื ื™ื•ืช.

ื–ื” ื ืขืฉื”

ืขืœื•ืช: 77 872.36
ื–ืžืŸ ื‘ื™ืฆื•ืข: 79 ืฉื ื™ื•ืช.

ืชื•ืฆืื” ื“ื™ ื˜ื•ื‘ื”. ืขืœื•ืช ื•ื–ืžืŸ ื‘ื™ืฆื•ืข ืžื•ืคื—ืชื™ื. ืœืคื™ื›ืš, ื”ืฉื™ืžื•ืฉ ื‘ืžื—ื™ืฆื” ื ื•ืชืŸ ืืช ื”ืืคืงื˜ ื”ืฆืคื•ื™ ื•ื‘ืื•ืคืŸ ื›ืœืœื™, ืื™ืŸ ื”ืคืชืขื•ืช.

ืชืฉืžื— ืืช ื”ืœืงื•ื—

ืชื•ืฆืื•ืช ื”ื‘ื“ื™ืงื” ื”ื•ืฆื’ื• ืœืœืงื•ื— ืœื‘ื“ื™ืงื”. ื•ืื—ืจื™ ืฉื‘ื“ืงื• ืืช ื–ื”, ื”ื ืงื™ื‘ืœื• ืคืกืง ื“ื™ืŸ ืงืฆืช ืœื ืฆืคื•ื™: "ื ื”ื“ืจ, ื—ืœืงื• ืืช ื˜ื‘ืœืช ื”"ื ืชื•ื ื™ื".

ื›ืŸ, ืื‘ืœ ื‘ื“ืงื ื• ื˜ื‘ืœืช "ืžืฉืœื•ื—" ืฉื•ื ื” ืœื—ืœื•ื˜ื™ืŸ; ื‘ื˜ื‘ืœื” "ื ืชื•ื ื™ื" ืื™ืŸ ืืช ื”ืฉื“ื” "SHIPMENT_DATE".

ืื™ืŸ ื‘ืขื™ื”, ื”ื•ืกืฃ, ืฉื ื”. ื”ืขื™ืงืจ ืฉื”ืœืงื•ื— ื™ื”ื™ื” ืžืจื•ืฆื” ืžื”ืชื•ืฆืื”, ืคืจื˜ื™ ื”ื™ื™ืฉื•ื ืื™ื ื ื—ืฉื•ื‘ื™ื ื‘ืžื™ื•ื—ื“.

ื—ืœื•ืงืช "ื ืชื•ื ื™ื" ื‘ื˜ื‘ืœื” ื”ืจืืฉื™ืช

ื‘ืื•ืคืŸ ื›ืœืœื™, ืœื ื”ืชืขื•ืจืจื• ืงืฉื™ื™ื ืžื™ื•ื—ื“ื™ื. ืื ื›ื™, ืืœื’ื•ืจื™ืชื ื”ื—ืœื•ืงื”, ื›ืžื•ื‘ืŸ, ื”ืฉืชื ื” ื‘ืžืงืฆืช.

ื”ื•ืกืคืช ื”ืขืžื•ื“ื” "SHIPMENT_DATA" ืœื˜ื‘ืœืช "ื ืชื•ื ื™ื".

psql -h ั…ะพัั‚ -U ะฑะฐะทะฐ -d ัŽะทะตั€
=> ALTER TABLE data ADD COLUMN "SHIPMENT_DATE" timestamp without time zone ;

ืžืœื ืืช ื”ืขืจื›ื™ื ืฉืœ ื”ืขืžื•ื“ื” "SHIPMENT_DATA" ื‘ื˜ื‘ืœื” "ื ืชื•ื ื™ื" ืขื ื”ืขืจื›ื™ื ืฉืœ ื”ืขืžื•ื“ื” ื‘ืื•ืชื• ืฉื ืžื˜ื‘ืœืช "ืžืฉืœื•ื—"

-----------------------------
--update_data.sql
--updating for altered table "data" to values of "shipment_data" from the table "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 'Total %',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 'row count = % , from %',row_count,total_rows;
  END LOOP;

end
$$;

ืฉืžื•ืจ dump ืฉืœ ื˜ื‘ืœืช "ื ืชื•ื ื™ื".

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

ืฆื•ืจ ืžื—ื“ืฉ ืืช ื”ื˜ื‘ืœื” ื”ืžื—ื•ืœืงืช "ื ืชื•ื ื™ื"

--create_partition_data.sql
--create partitions for the table "wafer data" by range column "shipment_data" with one month duration
--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 '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 data';
  drop table data cascade ;


  RAISE NOTICE 'CREATE PARTITIONED TABLE 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 'CREATE PARTITIONS FOR TABLE 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") ; 

      --Init borders
      IF   begin_year = '0' THEN
       RAISE NOTICE '***Init borders';
       first_flag := true ; --first time flag
       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;

      -- Check current date into borders NOT for First time

      RAISE NOTICE 'Current data = %',to_char( to_date( current_year||'.'||current_month, 'YYYY.MM'), 'YYYY.MM');
      RAISE NOTICE 'Begin data = %',to_char( to_date( begin_year||'.'||begin_month, 'YYYY.MM'), 'YYYY.MM');
      RAISE NOTICE 'Next data = %',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 '***CONTINUE';
         CONTINUE ; 
      ELSE
       --NEW borders only for second and after time 
       RAISE NOTICE '***NEW BORDERS';
       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 'PARTITION NUMBER % , TABLE NAME =%',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 NAME =%',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 NAME =%',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 NAME =%',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 NAME =%',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 NAME =%',index_name;
      EXECUTE format('CREATE INDEX ' || quote_ident(index_name) || ' ON '|| quote_ident(partition_name) ||' USING btree ("SHIPMENT_DATE") TABLESPACE pg_default ' ) ; 

      --Drop first time flag
      first_flag := false ;

  END LOOP;
end
$$;

ื˜ืขืŸ ืืช ื”-dump ืฉื ื•ืฆืจ ื‘ืฉืœื‘ 3.

pg_restore -h ั…ะพัั‚ -ัŽะทะตั€ -d ะฑะฐะทะฐ --data-only --format=c --table=data --verbose  data.dmp > data_restore.log 2>&1

ืฆื•ืจ ืงื˜ืข ื ืคืจื“ ืขื‘ื•ืจ ื ืชื•ื ื™ื ื™ืฉื ื™ื

---------------------------------------------------
--create_partition_for_old_dates.sql
--create partitions for keeping old dates 
--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 'Old date is %',rec_shipment_date.min_date ;

      partition_name := 'data_old_dates'  ;

      RAISE NOTICE 'PARTITION NAME IS %',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
$$;

ืชื•ืฆืื•ืช ืกื•ืคื™ื•ืช:

ื”ื™ื”
ืขืœื•ืช: 502 997.55
ื–ืžืŸ ื‘ื™ืฆื•ืข: 505 ืฉื ื™ื•ืช.

ื–ื” ื ืขืฉื”
ืขืœื•ืช: 68 533.70
ื–ืžืŸ ื‘ื™ืฆื•ืข: 69 ืฉื ื™ื•ืช

ืจืื•ื™, ื“ื™ ืจืื•ื™. ื•ื‘ื”ืชื—ืฉื‘ ื‘ื›ืš ืฉื‘ื“ืจืš ื”ืฆืœื—ื ื• ืœืฉืœื•ื˜ ืคื—ื•ืช ืื• ื™ื•ืชืจ ื‘ืžื ื’ื ื•ืŸ ื”ื—ืœื•ืงื” ื‘-PostgreSQL 10 - ืชื•ืฆืื” ืžืฆื•ื™ื ืช.

ืกื˜ื™ื™ื” ืœื™ืจื™ืช

ื”ืื ืืคืฉืจ ืœืขืฉื•ืช ืืคื™ืœื• ื™ื•ืชืจ ื˜ื•ื‘ - YES, YOU CAN!ืœืฉื ื›ืš ืขืœื™ืš ืœื”ืฉืชืžืฉ ื‘-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 ;

ืฉื•ื‘ ืื ื• ืžืฉื›ืชื‘ื™ื ืืช ื”ื‘ืงืฉื”:
ืฉืื™ืœืชื” ื‘ืืžืฆืขื•ืช ืชืฆื•ื’ื” ืžืžื•ืžืฉืช

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

ื•ื ืงื‘ืœ ืชื•ืฆืื” ื ื•ืกืคืช:
ื”ื™ื”
ืขืœื•ืช: 502 997.55
ื–ืžืŸ ื‘ื™ืฆื•ืข: 505 ืฉื ื™ื•ืช

ื–ื” ื ืขืฉื”
ืขืœื•ืช: 42 481.16
ื–ืžืŸ ื‘ื™ืฆื•ืข: 43 ืฉื ื™ื•ืช.

ืื ื›ื™, ื›ืžื•ื‘ืŸ, ืชื•ืฆืื” ืžื‘ื˜ื™ื—ื” ื›ื–ื• ืžื˜ืขื”; ื™ืฉ ืœืจืขื ืŸ ืจืขื™ื•ื ื•ืช. ืื– ื”ื–ืžืŸ ื”ื›ื•ืœืœ ืœืงื‘ืœืช ื ืชื•ื ื™ื ืœื ื™ืขื–ื•ืจ ื”ืจื‘ื”. ืื‘ืœ ื‘ืชื•ืจ ื ื™ืกื•ื™ ื–ื” ื“ื™ ืžืขื ื™ื™ืŸ.

ืœืžืขืฉื”, ื›ืคื™ ืฉื”ืชื‘ืจืจ, ืฉื•ื‘ ืชื•ื“ื” asmm ื•ื”ื‘ืจื•!- ื ื™ืชืŸ ืœืฉืคืจ ืขื•ื“ ื™ื•ืชืจ ืืช ื”ืฉืื™ืœืชื”.

ืื—ืจื™ืช ื“ื‘ืจ

ืื– ื”ืœืงื•ื— ืžืจื•ืฆื”. ื• ืฆื•ืจืš ืœื ืฆืœ ืืช ื”ืžืฆื‘.

ืžืฉื™ืžื” ื—ื“ืฉื”: ืžื” ืืชื” ื™ื›ื•ืœ ืœื”ืžืฆื™ื ื›ื“ื™ ืœื”ืขืžื™ืง ื•ืœื”ืจื—ื™ื‘?

ื•ืื– ืื ื™ ื–ื•ื›ืจ - ื—ื‘ืจ'ื”, ืื™ืŸ ืœื ื• ื ื™ื˜ื•ืจ ืฉืœ ืžืกื“ื™ ื”ื ืชื•ื ื™ื ืฉืœ PostgreSQL ืฉืœื ื•.

ื™ื“ ืขืœ ื”ืœื‘, ื™ืฉ ืขื“ื™ื™ืŸ ืงืฆืช ื ื™ื˜ื•ืจ ื‘ืฆื•ืจื” ืฉืœ Cloud Watch ื‘-AWS. ืื‘ืœ ืžื” ื”ื™ืชืจื•ืŸ ืฉืœ ื ื™ื˜ื•ืจ ื–ื” ืขื‘ื•ืจ ื”-DBA? ื‘ืื•ืคืŸ ื›ืœืœื™, ื›ืžืขื˜ ืืฃ ืื—ื“.

ืื ื™ืฉ ืœืš ื”ื–ื“ืžื ื•ืช ืœืขืฉื•ืช ืžืฉื”ื• ืฉื™ืžื•ืฉื™ ื•ืžืขื ื™ื™ืŸ ืขื‘ื•ืจ ืขืฆืžืš, ืืชื” ืœื ื™ื›ื•ืœ ืœื ืœื ืฆืœ ืืช ื”ื”ื–ื“ืžื ื•ืช ื”ื–ื•...
ืœ

Happy Party ืื• ื›ืžื” ืฉื•ืจื•ืช-ื–ื›ืจื•ื ื•ืช ืฉืœ ื”ื™ื›ืจื•ืช ืขื ืžื—ื™ืฆื•ืช ื‘-PostgreSQL10

ื›ืš ื”ื’ืขื ื• ืœื—ืœืง ื”ืžืขื ื™ื™ืŸ ื‘ื™ื•ืชืจ:

3 ื‘ื“ืฆืžื‘ืจ 2018.
ืงื‘ืœืช ื”ื—ืœื˜ื” ืœื”ืชื—ื™ืœ ื‘ืžื—ืงืจ ืขืœ ื™ื›ื•ืœื•ืช ื–ืžื™ื ื•ืช ืœื ื™ื˜ื•ืจ ื”ื‘ื™ืฆื•ืขื™ื ืฉืœ ืฉืื™ืœืชื•ืช PostgreSQL.

ืื‘ืœ ื–ื” ืกื™ืคื•ืจ ืื—ืจ ืœื’ืžืจื™.

ื”ืžืฉืš ื™ื‘ื•ืโ€ฆ

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”