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 提取文件 |