快速找出DB2分区键设置不正确的表

Posted zhangjianying

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速找出DB2分区键设置不正确的表相关的知识,希望对你有一定的参考价值。

 

DB2建立表的时候可以设置一个分区键,默认的情况下都是根据建表者自己的开发经验来决定。如果万一分区键没有设置正确,就会造成数据库节点数据分配不均匀。那么如何快速的找出哪些表的分区键设置不正确呢??
自己写了一个不足130行的小程序就可以解决这个问题了

// ~--- non-JDK imports --------------------------------------------------------

import  org.apache.commons.beanutils.DynaBean;
import  org.apache.commons.beanutils.RowSetDynaClass;

// ~--- JDK imports ------------------------------------------------------------

import  java.sql.Connection;
import  java.sql.DriverManager;
import  java.sql.ResultSet;
import  java.sql.SQLException;
import  java.sql.Statement;
import  java.util.List;

public   class  Main {
    
private   static  String
        url      
=   " jdbc:db2://:/ " ,
        username 
=   " hndp " ,
        password 
=   " hndp " ;

    
private   static  RowSetDynaClass getResultSet(String sql) {
        Connection      conn  
=   null ;
        Statement       staem 
=   null ;
        ResultSet       rs    
=   null ;
        RowSetDynaClass rsdc  
=   null ;

        
try  {
            Class.forName(
" com.ibm.db2.jcc.DB2Driver " );
            conn  
=  DriverManager.getConnection(url, username, password);
            staem 
=  conn.createStatement();
            rs    
=  staem.executeQuery(sql);
            rsdc  
=   new  RowSetDynaClass(rs);
        } 
catch  (Exception e) {
            e.printStackTrace();
        } 
finally  {
            
try  {
                
if  (rs  !=   null ) {
                    rs.close();
                }
                
if  (staem  !=   null ) {
                    staem.close();
                }
                
if  (conn  !=   null ) {
                    conn.close();
                }
            } 
catch  (SQLException e) {
                e.printStackTrace();
            }
        }

        
return  rsdc;
    }

    
public   static   void  main(String[] args) {
        
if  (args.length  <   5 ) {
            System.out.println(
" 参数少了!==》java Main 10.154.144.40 50000 DBNAME user pass schema % " );

            
return ;
        }

        url      
=   " jdbc:db2:// "   +  args[ 0 +   " : "   +  args[ 1 +   " / "   +  args[ 2 ];
        username 
=  args[ 3 ];
        password 
=  args[ 4 ];

        String SQL_QUERY_TABLE_NAME 
=
            
" select RTRIM(CREATOR)as schema,RTRIM(NAME) as tablename  from SYSIBM.SYSTABLES  where TYPE='T'   and CREATOR =' "
            
+  args[ 5 +   " '  AND NAME like ' "   +  args[ 6 +   " ' WITH UR " ;
        String SQL_T 
=
            
" select '#TALBE#' AS TABLENAME,A.PARTION,A.ROWS,B.ROWS_COUNT,A.ROWS*1.0/B.ROWS_COUNT, DEC(A.ROWS*1.0/B.ROWS_COUNT,4,2) as person  from  "
            
+   " (select COUNT(*) AS ROWS,dbpartitionnum(#KEY#) AS PARTION  "   +   "  FROM  "   +   "  #TALBE#  "
            
+   "  GROUP BY dbpartitionnum(#KEY#)  "   +   "  ) AS A,  "   +   "  (  "   +   "  select COUNT(*) AS ROWS_COUNT  "   +   "  FROM  "
            
+   "  #TALBE#  "   +   "  ) AS b  " ;
        String SQL_TIAOJIAN 
=
            
" select TABLENAME,MIN(PERSON) AS MIN,MAX(PERSON) AS MAX,MAX(PERSON)-MIN(PERSON) AS CHA  from (  "   +  SQL_T
            
+   " ) AS TABLE group by  TABLENAME WITH UR " ;
        RowSetDynaClass ResultTableName 
=  getResultSet(SQL_QUERY_TABLE_NAME);

        
//  获取所有表名
        List rows  =  ResultTableName.getRows();
        
int   size  =  rows.size();

        System.out.println(
" 表架构名: "   +  args[ 5 ]);
        System.out.println(
" 表筛选名: "   +  args[ 6 ]);
        System.out.println(
" 表名 | 最大分区占比 | 最小分区占比 | 差值 " );

        
for  ( int  i  =   0 ; i  <  size; i ++ ) {
            DynaBean DBean 
=  (DynaBean) rows.get(i);

            
//  扫描所有表的情况
            RowSetDynaClass Result  =  getResultSet(setKeyToSQLString(SQL_TIAOJIAN, DBean.get( " tablename " ).toString(),
                                         DBean.get(
" schema " ).toString()));
            List Listrows 
=  Result.getRows();

            
if  (Listrows.size()  >   0 ) {
                DynaBean DBean2 
=  (DynaBean) Listrows.get( 0 );

                System.out.println(DBean2.get(
" tablename " +   "  |  "   +  DBean2.get( " max " +   "  |  "   +  DBean2.get( " min " )
                                   
+   "  |  "   +  DBean2.get( " cha " ));
            }
        }       
    }

    
private   static  String setKeyToSQLString(String sourceSQL, String TableName, String Schmea) {
        String SQL_KEY 
=
            
" select name from SYSIBM.SYSCOLUMNS   where PARTKEYSEQ=1   AND TBNAME ='#TABLENAME#'  AND TBCREATOR='#SCHEMA#'  WITH UR " ;

        SQL_KEY 
=  SQL_KEY.replaceAll( " #TABLENAME# " , TableName);
        SQL_KEY 
=  SQL_KEY.replaceAll( " #SCHEMA# " , Schmea);

        RowSetDynaClass ResultTableName 
=  getResultSet(SQL_KEY);
        List            rows            
=  ResultTableName.getRows();
        DynaBean        DBean           
=  (DynaBean) rows.get( 0 );

        
//  替换表名
        sourceSQL  =  sourceSQL.replaceAll( " #TALBE# " , Schmea  +   " . "   +  TableName);

        
return  sourceSQL.replaceAll( " #KEY# " , DBean.get( " name " ).toString());
    }
}

执行的方式和参数在CLI方式下:java -jar Partions_fat.jar 10.154.144.40 50000 数据库名 用户名 密码 架构名 表的筛选条件 

 前面2个是 IP 和数据端口 (该程序可以在安装jre的机器上执行,不必需要安装IBM DB2客户端)

执行的效果为:

(分区正常的)

(分区不太正常的现象)

说面一下:

最大分区占比 : 是该表在所有节点所占的最大比之;

最小分区占比 : 是该表在所有节点所占的最小比之;

差值:最大分区占比-最小分区占比

一个表的分区键如果设置的正确那么差值就应该是0.01~0.05之间,如果不正确那么就可以去找找原因了。

可能你会说程序只用Sysout打印出来而已,不好备查。OK , 你执行的

 java -jar Partions_fat.jar 10.154.144.40 50000 数据库名 用户名 密码 架构名 表的筛选条件 >> 1.txt

 

提供一个独立的打包文件下载:

 当您的朋友需要提取此文件时只需:
     匿名提取文件连接 http://pickup.mofile.com/1627308298166791
     或登录Mofile,使用提取码 1627308298166791 提取文件

以上是关于快速找出DB2分区键设置不正确的表的主要内容,如果未能解决你的问题,请参考以下文章

快速排序

PHP 快速排序

java快速排序解析

找出归档或分区策略?

排序算法-快速排序

如何解锁DB2中被锁定的表