DB2建立表的时候可以设置一个分区键,默认的情况下都是根据建表者自己的开发经验来决定。如果万一分区键没有设置正确,就会造成数据库节点数据分配不均匀。那么如何快速的找出哪些表的分区键设置不正确呢??
自己写了一个不足130行的小程序就可以解决这个问题了
//
~---non-JDKimports--------------------------------------------------------
import
org.apache.commons.beanutils.DynaBean;
import
org.apache.commons.beanutils.RowSetDynaClass;
//
~---JDKimports------------------------------------------------------------
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
RowSetDynaClassgetResultSet(Stringsql){
Connectionconn
=
null
;
Statementstaem
=
null
;
ResultSetrs
=
null
;
RowSetDynaClassrsdc
=
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
(Exceptione){
e.printStackTrace();
}
finally
{
try
{
if
(rs
!=
null
){
rs.close();
}
if
(staem
!=
null
){
staem.close();
}
if
(conn
!=
null
){
conn.close();
}
}
catch
(SQLExceptione){
e.printStackTrace();
}
}
return
rsdc;
}
public
static
void
main(String[]args){
if
(args.length
<
5
){
System.out.println(
"
参数少了!==》java Main10.154.144.4050000DBNAMEuserpassschema%
"
);
return
;
}
url
=
"
jdbc:db2://
"
+
args[
0
]
+
"
:
"
+
args[
1
]
+
"
/
"
+
args[
2
];
username
=
args[
3
];
password
=
args[
4
];
StringSQL_QUERY_TABLE_NAME
=
"
selectRTRIM(CREATOR)asschema,RTRIM(NAME)astablenamefromSYSIBM.SYSTABLESwhereTYPE='T'andCREATOR='
"
+
args[
5
]
+
"
'ANDNAMElike'
"
+
args[
6
]
+
"
'WITHUR
"
;
StringSQL_T
=
"
select'#TALBE#'ASTABLENAME,A.PARTION,A.ROWS,B.ROWS_COUNT,A.ROWS*1.0/B.ROWS_COUNT,DEC(A.ROWS*1.0/B.ROWS_COUNT,4,2)aspersonfrom
"
+
"
(selectCOUNT(*)ASROWS,dbpartitionnum(#KEY#)ASPARTION
"
+
"
FROM
"
+
"
#TALBE#
"
+
"
GROUPBYdbpartitionnum(#KEY#)
"
+
"
)ASA,
"
+
"
(
"
+
"
selectCOUNT(*)ASROWS_COUNT
"
+
"
FROM
"
+
"
#TALBE#
"
+
"
)ASb
"
;
StringSQL_TIAOJIAN
=
"
selectTABLENAME,MIN(PERSON)ASMIN,MAX(PERSON)ASMAX,MAX(PERSON)-MIN(PERSON)ASCHAfrom(
"
+
SQL_T
+
"
)ASTABLEgroupbyTABLENAMEWITHUR
"
;
RowSetDynaClassResultTableName
=
getResultSet(SQL_QUERY_TABLE_NAME);
//
获取所有表名
Listrows
=
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
++
){
DynaBeanDBean
=
(DynaBean)rows.get(i);
//
扫描所有表的情况
RowSetDynaClassResult
=
getResultSet(setKeyToSQLString(SQL_TIAOJIAN,DBean.get(
"
tablename
"
).toString(),
DBean.get(
"
schema
"
).toString()));
ListListrows
=
Result.getRows();
if
(Listrows.size()
>
0
){
DynaBeanDBean2
=
(DynaBean)Listrows.get(
0
);
System.out.println(DBean2.get(
"
tablename
"
)
+
"
|
"
+
DBean2.get(
"
max
"
)
+
"
|
"
+
DBean2.get(
"
min
"
)
+
"
|
"
+
DBean2.get(
"
cha
"
));
}
}
}
private
static
StringsetKeyToSQLString(StringsourceSQL,StringTableName,StringSchmea){
StringSQL_KEY
=
"
selectnamefromSYSIBM.SYSCOLUMNSwherePARTKEYSEQ=1ANDTBNAME='#TABLENAME#'ANDTBCREATOR='#SCHEMA#'WITHUR
"
;
SQL_KEY
=
SQL_KEY.replaceAll(
"
#TABLENAME#
"
,TableName);
SQL_KEY
=
SQL_KEY.replaceAll(
"
#SCHEMA#
"
,Schmea);
RowSetDynaClassResultTableName
=
getResultSet(SQL_KEY);
Listrows
=
ResultTableName.getRows();
DynaBeanDBean
=
(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 提取文件 |