PostgreSQL:高性能请求而不是大PG / SQL过程

时间:2017-11-24 11:26:36

标签: postgresql performance request plpgsql

我已经制定了一个大的PG / SQL程序来实现这个目标:

基于此"数据"表:

order | product
----------------
  1   |  A 
  1   |  B  
  2   |  A  
  2   |  D   
  3   |  A  
  3   |  C
  4   |  A  
  4   |  B
  5   |  Y  
  5   |  Z
  6   |  W  
  6   |  A
  7   |  A

我正在建立这张桌子:" DICO"

    order | couple | first | second
    -------------------------------
      1   |  A-B   |   A   |   B
      2   |  A-D   |   A   |   D
      3   |  A-C   |   A   |   C
      4   |  A-B   |   A   |   B
      5   |  Y-Z   |   Y   |   Z
      6   |  W-A   |   W   |   A

当我完全计算了这个dico表时(在DATA中可能需要超过一天的3.000.000行),我在桌子上做了一个请求,以便最好的情况发生:

order | count | total1stElem | %1stElem | total2ndElem | %2ndElem
------------------------------------------------------------------
A-B   |  2    |       6      |    33%   |     2        |    100%       
A-D   |  1    |       6      |    16%   |     1        |    100%      
A-C   |  1    |       6      |    16%   |     1        |    100%         
Y-Z   |  1    |       1      |    100%  |     1        |    100%     
W-A   |  1    |       1      |    100%  |     6        |    16%    

所以它的工作非常好,但我显然需要一种更好的表现方式:我认为它可以直接用一个好的(和大的)请求。我不知道是否有必要建立DICO表......!

这是大PG / SQL脚本:

-- Function: addinparamsales()

-- DROP FUNCTION addinparamsales();

CREATE OR REPLACE FUNCTION addinparamsales()
  RETURNS trigger AS
$BODY$

DECLARE
productstab varchar(14) [];
coupletabarray varchar(50) []; 
couplearrayTMP varchar(14) [];
couplevarcharconcat varchar(29);
v_allcmd data1%rowtype;
v_allproductincmd data1%rowtype;
v_alldico dico1%rowtype;
v_count_dico1 bigint;
v_total_dico1 bigint;
v_iterator_dico1 bigint;
v_count_integer bigint;
v_count1 bigint;
i bigint;
v_test varchar[];
v_test2 varchar(14)[];
tab_result varchar[];
items RECORD;
 r record;
 first varchar(50);
 second varchar(50);

    BEGIN
    IF (TG_OP = 'INSERT') THEN 

    TRUNCATE dico1;

    i = 0 ;

    FOR v_allcmd 
    IN  
    SELECT d.documentsourceid FROM data1 d GROUP BY d.documentsourceid ORDER BY d.documentsourceid ASC 

    LOOP
        productstab := null;

        FOR v_allproductincmd
        IN
        SELECT * FROM data1 d WHERE d.documentsourceid = v_allcmd.documentsourceid ORDER BY documentsourceid ASC, productid ASC

        LOOP
            productstab := array_append(productstab, v_allproductincmd.productid);
        END LOOP;

        FOR i IN 1 .. array_upper(productstab, 1)
            LOOP

            coupletabarray := array_append(coupletabarray,productstab[i]);
            END LOOP;

         FOR v_test2
            IN 
            SELECT * FROM "twouplets"(coupletabarray) ORDER BY twouplets DESC   

            LOOP
                IF array_length(v_test2,1) IS NOT NULL -- not empty array
                THEN
                    FOR i IN 1 .. array_length(v_test2,1)
                    LOOP
                        couplearrayTMP := array_append(couplearrayTMP,v_test2[i]);
                    END LOOP;

                FOR i IN 1 .. array_length(couplearrayTMP,1)
                LOOP
                    IF i = 1 THEN
                        couplevarcharconcat := CONCAT(couplearrayTMP[i]);
                        first := couplearrayTMP[i];
                    ELSE
                        couplevarcharconcat := CONCAT(couplevarcharconcat,'|',couplearrayTMP[i]);
                        second := couplearrayTMP[i];
                    END IF ;

                END LOOP;
                    INSERT INTO dico1 (documentsourceid, couple,first, second) VALUES (v_allcmd.documentsourceid,couplevarcharconcat, first, second);
                    couplevarcharconcat := null;
                    couplearrayTMP := null;
                END IF;

            END LOOP;
        coupletabarray := null;
    END LOOP;
        END IF;
        RETURN NULL; 
    END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION addinparamsales()
  OWNER TO postgres;

有人有一些想法来改进这个程序吗?例如,使用请求而不是这个大的PG / SQL过程吗?

0 个答案:

没有答案