企业Postgresql查询性能达数百万行

时间:2018-07-18 11:54:47

标签: sql plpgsql query-performance postgresql-9.5 sqlperformance

请找到以下过程.cursor(cntry_lobreg_lang_cur)包含23749782行,视图(技能)具有629行。加入和检索行需要3个多小时。它使用100%CPU(8核)和Memory(64GB)并崩溃。

请您建议如何提高性能。

 CREATE TYPE lang_tab AS ( countryid character varying(255), lob_id character varying(255), region_id numeric(10,0), language_id character varying(255), roleid character varying(255), language_id_flag character varying(5), roleid_flag character varying(5), course_id character varying(255), skill_id character varying(255), language_id_null character varying(5), roleid_null character varying(5), lob_name character varying(256) );

CREATE TYPE lang_obj AS lang_tab;


DECLARE
    CURSOR cntry_lobreg_lang_cur is
        SELECT *
        FROM
               LOBREG_LANGROLE
        ;

    _array_type lang_obj := lang_obj();
BEGIN

    OPEN cntry_lobreg_lang_cur;
    LOOP
        FETCH cntry_lobreg_lang_cur BULK COLLECT
        INTO  _array_type LIMIT 30000
        ;

        EXIT WHEN _array_type.count = 0;
        dbms_output.put_line('_array_type : '
        ||_array_type.COUNT);

        INSERT        INTO LANGROL_TAB
               (COUNTRYID
                    , LOB_ID
                    , REGION_ID
                    , LANGUAGE_ID
                    , ROLEID
                    , SKILL_ID
                    , LOB_NAME
               )
        SELECT
               A.COUNTRYID
             , A.LOB_ID
             , A.REGION_ID
             , A.LANGUAGE_ID
             , A.ROLEID
             , B.PRODUCTID
             , A.LOB_NAME
        FROM
               TABLE(_array_type) A
             , skills             B
        WHERE
               A.LOB_NAME=B.LINE_OF_BUSINESS
        ;

    END LOOP;

    CLOSE cntry_lobreg_lang_cur;

END;

如有任何疑问,请告诉我。

1 个答案:

答案 0 :(得分:3)

首先将逻辑重写为单个语句:

INSERT INTO LANGROL_TAB (COUNTRYID, LOB_ID, REGION_ID, LANGUAGE_ID, ROLEID, SKILL_ID, LOB_NAME)
    SELECT l.COUNTRYID, l.LOB_ID, l.REGION_ID, l.LANGUAGE_ID, l.ROLEID,
           B.PRODUCTID,
           l.LOB_NAME
    FROM LOBREG_LANGROLE l JOIN
         skills s
         ON l.LOB_NAME = s.LINE_OF_BUSINESS;

然后,如果您没有索引,请在skills(LINE_OF_BUSINESS, PRODUCTID)上添加索引。

注意:

  • 避免光标。
  • 始终使用明确,正确,标准JOIN语法。 从不FROM子句中使用逗号。
  • 使用有意义的表别名。 ab毫无意义;表名的缩写。