快速找出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());
}
}
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分区键设置不正确的表的主要内容,如果未能解决你的问题,请参考以下文章