zoukankan      html  css  js  c++  java
  • 记一次postgresql数据库函数执行问题

     
     

    一、函数说明:

    首先编写了三个函数:
    func_init.sql
    func_process.sql
    func_uuid.sql
     
     
    1、func_init.sql 入参为一个int类型number,根据传入的number做循环,循环调用func_process.sql。
    ...
    BEGIN
    
    FOR i IN 1..num LOOP
    
        SELECT func_process.sql() INTO counts;
    
        if counts = 0 then return 'mac地址已使用完';
        end if;
    
    end LOOP;
    ...
     
    2、func_process.sql 没有入参,出参为完成状态值integer,里面共分五步:
        a)、查询macInfo表,得到一条state=0的mac值【该表有65w条数据,且只有mac和state两个字段,mac为主键】
    select mac from macInfo where state = 0 limit 1;
        b)、调用func_uuid.sql,得到uuid【该方法通过plpythonu语言编写,生成UUID】
        c)、生成各个sequence(大概12个)
        d)、组装12个insert语句(12张表)【这里用到了第a步里得到的mac】
        e)、更新macInfo表,将mac值对应的数据的state改为1。
     
    3、func_uuid.sql
    通过plpythonu语言编写,生成UUID,与sql无关。
     
     

    二、postgresql函数问题:

    单个函数就是一个事物,无法主动提交事物。
    也就是说,我func_init传入的值是多少,那么必须这些全部处理完才会提交事务,中途无法主动提交。
     

    三、前提如下:

    由于一开始没有特别的考虑性能问题,使用了insert into,而不是copy。
    macInfo表里state没有建立索引。
    一开始macInfo表的所有state都为0。
    写了一个python脚本,在服务器循环调用func_init(10000),调用了65次,用来规避postgresql无法主动提交事务问题。
     

    四、发生的问题以及排查

    1、一开始跑的时候,
    前几次func_init(10000),也就是执行10000次func_process,耗时135s。
    func_init(10000)跑到第60次的时候,发现耗时非常久,需要20分钟多。
    也就是速度慢了10倍。
     
    检查postgresql所在服务器,发现当执行函数的时候,会将一个cpu占到90%,占所有cpu的6%。
    当这个函数执行完成时,几乎不占,因此可以确定是这个函数造成的。
     
    2、经过排除,发现是第a步,查询mac非常慢,每次耗时100ms。原本耗时是7ms。
    猜想macInfo表中state当时值分布中为0的已经很少,都是为1的,且没有索引导致查询慢。
    >> select "state", "count"("state") from macinfo GROUP BY state;
    >> 
    state count
    1    641153
    0    15000
    3、因此为state加上索引。
    CREATE INDEX "idx_macinfo_state" ON "usr"."macinfo" USING BTREE ("state");
    4、再次执行,发现速度还是很慢,几乎没有改变。
    5、既然索引没用,那么我删掉state为1的数据,只留下15000条state为0的数据。
    create table usr.macinfo_copy as select * from usr.macinfo;
    DELETE FROM usr.macinfo where "state" <> 0;
    6、再次执行,本次执行了1000条,发现耗时680s,换算成10000条也就是 10分钟多点。
    相比快了一倍,但是和最开始比还是慢了5倍。因此该方法还是不行
     
    7、还原macinfo表,将数据还原成最初形式。再次执行。速度还是很慢,1000条500s。
     
    五、小结
    发现就是macinfo表的原因,而且必定能重现。
     

    文章源自微信公众号【刍荛采葑菲】,转载请注明。

  • 相关阅读:
    c/c++基础 输入函数/流
    数据库的码/键
    sql plus笔记
    cmd delete oracle related
    CAN总线
    SAR ADC : 逐次逼近寄存器型(SAR)模数转换器(ADC)
    Cortex-M3寄存器等基础知识
    Cortex-M3知识点
    ARM指令和Thumb指令区别
    8051、ARM、AVR
  • 原文地址:https://www.cnblogs.com/churao/p/8494304.html
Copyright © 2011-2022 走看看