Greenplum批量操作,数据库里面作删除更新速度最快

余生长醉 提交于 2019-12-27 02:40:59

这是记一次线上GP大数据库 大量重复问题解决方案  1 建临时表,把重复的数据备份,2 在备份库用查询条件去删除正式表

 最近在玩Greenplum 数据库, 一款分布式的数据库 ,MPP架构,但是有好的也有不如意的,总体感觉还是不错,底层数据库还是用PostgreSQL8.2版本, 因为我是GP4.2嘛, 最新版本的GP6.0是基本PostgreSQL9.2,在性能上提高了不少。

 先说下,遇到的坑和一些数据问题,删除数据和更新数据, 分区表等一些概念

依赖  放在项目的lib下面

    <dependency>
            <groupId>com.fbcds</groupId>
            <artifactId>fbcds</artifactId>
            <version>1.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/resources/lib/greenplum.jar</systemPath>
        </dependency>

连接数据库,当然还有其它的方法查询封装

// 饿汉式
    private static DruidDataSource dataSource = null;

    static {
        dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.pivotal.jdbc.GreenplumDriver");
        dataSource.setUsername("gptest");
         dataSource.setPassword("123456“);
     dataSource.setUrl("jdbc:pivotal:greenplum://192.168.0.1:8088;DatabaseName=npp_db");

        dataSource.setInitialSize(10);
        dataSource.setMinIdle(10);
        dataSource.setMaxActive(50); // 启用监控统计功能
        dataSource.setTimeBetweenEvictionRunsMillis(300000);
        dataSource.setValidationQuery("SELECT 'x'");
        // 配置一个连接在池中最小生存的时间,单位是毫秒
        dataSource.setMinEvictableIdleTimeMillis(300000);


    }

 

批量操作代码  主要是为了操作线上数据,因为有大量重复,分区表处理起来,超级麻烦,就先建临时表保存要删除的数据,

然后,利用数据库相关性,先查询临时表的ID再去删除正式表,操作与同插入的方式,在数据库内部进行操作,速度会快很多,解决思路就是如此,在数据库里作删除,而不是取到程序里再操作,  

解决问题的思路很重要,要去套用哪种处理方式最快。

String tablename = Snmp_Table;
        String sql_info =
                " insert into da_his.test_five_data_his_1 select min(\"id\") \"id\",min(\"timestamp\") as \"timestamp\",max(snmp_index) "
                        + "as snmp_index,max(snmp) as snmp,max(\"in\") as \"in\",max(\"out\") as \"out\"  from " + tablename
                        + " where \"timestamp\">=? " + " and \"timestamp\"<=? and  (" + sl.toString()
                        + ") and \"in\"<'1250000000000' and  \"out\"<'1250000000000' group by "
                        + "\"timestamp\" ,snmp_index  having count(\"timestamp\")>1 ";
        //List<Map<String, Object>> list_info = (List<Map<String, Object>>) Gp_tools.query(sql_info, new Object[] {obj[0], obj[1]},
        //       new AllObjectMapper());
        Gp_tools.updateTemp(sql_info, new Object[] {obj[0], obj[1]}, true);

 public static boolean updateTemp(String sql, Object[] obj, boolean isGenerateKey) {
        Connection conn = null;

        boolean bFlag = true;
        try {
            conn = JdbcUtil.getConnection();
            PreparedStatement pstmt = conn.prepareStatement(sql);
           /* for (int i = 0; i < obj.length; i++) {
                pstmt.setObject(i + 1, obj[i]);
            }*/
            pstmt.setObject(1, obj[0]);
            pstmt.setObject(2, obj[1]);
            pstmt.executeUpdate();
            conn.commit();
        } catch (SQLException ex) {
            ex.printStackTrace();
        } finally {
            try {
                JdbcUtil.releaseConnection(conn);
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }
        return bFlag;
    }

另外的批量删除, 操作也很慢

delete from da_his.tb_dev_five_data_1 as devfive using (values ('877|54',277,1444413654),('877|54',277,1444425009),('877|54',277,1444413674)) as tmp(snmp_index,snmp,"id") where 
 devfive.snmp_index=tmp.snmp_index and devfive.snmp=tmp.snmp and devfive.id=tmp.id ;  

批量更新操作,原理是一样的, 但是在数据量几十亿又分成几百个分区, 这种操作分分钟能搞崩掉

 update test set info=tmp.info from (values (1,'new1'),(2,'new2'),(6,'new6')) as tmp (id,info) where test.id=tmp.id; 

批量删除有可能如下 官网解释的,最后group by id字段必须是唯一

DELETE FROM test
WHERE ctid NOT IN (
SELECT min(ctid)
FROM test
GROUP BY x);
(where 'x' is the unique column list)

 

最张解决方案  从临时表的备份表查询要删除的数据,程序里拼接下面的SQL

delete from da_his.tb_dev_five_data_1  where snmp=472 and "id" in(5357929218,5357927657,5357929285,5357928550,5357929262);

多线程跑起来,很快, 可能晚上用的人少,删除非常快

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!