SqlComparison
package com.ufo.leftjoin;
import java.security.MessageDigest;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.log4j.Logger;
// Used for JDBC connection to DB
class DBParam {
public static final String Driver = "oracle.jdbc.driver.OracleDriver";
public static final String DbUrl = "。。。。。。。。MSAPDB";
public static final String User = "R。。。。。。。A_USER";
public static final String Pswd = "FF。。。。。。。。wCP";
}
// Used for collection sort
class KeyValue implements Comparable<KeyValue> {
String key;
Object value;
@Override
public int compareTo(KeyValue another) {
return this.key.compareTo(another.key);
}
}
// Used for hold columns
class DhItem{
String order_no;
String shipper_code;
String vehicle_name;
String vehicle_code;
String reason_name_mobile;
String status_name_mobile;
public String toString() {
List<String> ls=new ArrayList<String>();
ls.add(order_no);
ls.add(shipper_code);
ls.add(vehicle_name);
ls.add(vehicle_code);
ls.add(reason_name_mobile);
ls.add(status_name_mobile);
return String.join(",", ls);
}
}
// Left jion/inner join comparison
public class SqlComparison {
private static Logger log = Logger.getLogger(SqlComparison.class);
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try {
Class.forName(DBParam.Driver).newInstance();
Properties pro = new Properties();
pro.setProperty("user", DBParam.User);// 这里不是username或是usr!
pro.setProperty("password", DBParam.Pswd);// 这里不是pswd
// pro.setProperty("initialSize", "10");
// pro.setProperty("maxActive", "12");
// pro.put("remarksReporting","true");// 这一句才能让rs.getString("REMARKS")起作用
conn = DriverManager.getConnection(DBParam.DbUrl, pro);
stmt = conn.createStatement();
SqlComparison sc = new SqlComparison();
sc.queryTotalCntinDH(stmt);
sc.testLeftJoin(stmt);
sc.testInnerJoin(stmt);
sc.compareTwoPlan(stmt);
} catch (Exception e) {
System.out.print(e.getMessage());
e.printStackTrace();
} finally {
try {
stmt.close();
conn.close();
} catch (SQLException e) {
log.error("Can't close stmt/conn because of " + e.getMessage());
}
}
}
/**
* Compare left to inner
* @param stmt
* @throws SQLException
*/
private void compareTwoPlan(Statement stmt) throws SQLException {
long startMs = System.currentTimeMillis();
String leftSql=getLeftjoinSql();
Map<String,DhItem> leftMap=new HashMap<String,DhItem>();
ResultSet rs = stmt.executeQuery(leftSql);
while (rs.next()) {
DhItem dhItem=new DhItem();
dhItem.order_no=rs.getString("order_no");
dhItem.shipper_code=rs.getString("shipper_code");
dhItem.vehicle_name=rs.getString("vehicle_name");
dhItem.vehicle_code=rs.getString("vehicle_code");
dhItem.reason_name_mobile=rs.getString("reason_name_mobile");
dhItem.status_name_mobile=rs.getString("status_name_mobile");
leftMap.put(toMD5(dhItem.toString()), dhItem);
}
String innerSql=getNewInnerSql();
Map<String,DhItem> innerMap=new HashMap<String,DhItem>();
rs = stmt.executeQuery(innerSql);
while (rs.next()) {
DhItem dhItem=new DhItem();
dhItem.order_no=rs.getString("order_no");
dhItem.shipper_code=rs.getString("shipper_code");
dhItem.vehicle_name=rs.getString("vehicle_name");
dhItem.vehicle_code=rs.getString("vehicle_code");
dhItem.reason_name_mobile=rs.getString("reason_name_mobile");
dhItem.status_name_mobile=rs.getString("status_name_mobile");
innerMap.put(toMD5(dhItem.toString()), dhItem);
}
List<DhItem> onlyInLeftLs=new ArrayList<DhItem>();
int count=0;
for(String key:leftMap.keySet()) {
if(innerMap.containsKey(key)) {
count++;
}else {
DhItem dhItem=leftMap.get(key);
onlyInLeftLs.add(dhItem);
}
}
log.info("There are "+toEastNumFormat(count)+" records in both left and inner.");
log.info("There are "+toEastNumFormat(onlyInLeftLs.size())+" records only in left.");
List<DhItem> onlyInInnerLs=new ArrayList<DhItem>();
count=0;
for(String key:innerMap.keySet()) {
if(leftMap.containsKey(key)) {
count++;
}else {
DhItem dhItem=innerMap.get(key);
onlyInInnerLs.add(dhItem);
}
}
log.info("There are "+toEastNumFormat(count)+" records in both left and inner.");
log.info("There are "+toEastNumFormat(onlyInInnerLs.size())+" records only in inner.");
long endMs = System.currentTimeMillis();
log.info("It takes "+ms2DHMS(startMs,endMs)+" to run function:'compareTwoPlan'.");
}
private String getLeftjoinSql() {
StringBuilder sb = new StringBuilder();
sb.append(" SELECT ");
sb.append(" DH1.ORDER_NO, ");
sb.append(" DH1.SHIPPER_CODE , ");
sb.append(" DH1.VEHICLE_NAME, ");
sb.append(" DH1.VEHICLE_CODE , ");
sb.append(" DH1.REASON_NAME_MOBILE, ");
sb.append(" DH1.STATUS_NAME_MOBILE ");
sb.append(" from ");
sb.append(" DELIVERY_HISTORY DH1 ");
sb.append(" left JOIN DELIVERY_HISTORY DH2 on ");
sb.append(" DH1.SHIPPER_CODE = DH2.SHIPPER_CODE ");
sb.append(" and DH1.ORDER_NO = DH2.ORDER_NO ");
sb.append(" and DH2.UPDATED_DATETIME > DH1.UPDATED_DATETIME ");
sb.append(" where DH2.UPDATED_DATETIME IS NULL ");
sb.append(" and DH1.DISABLED_FLG = 0 ");
String sql = sb.toString();
return sql;
}
private String getInnerSql() {
StringBuilder sb = new StringBuilder();
sb.append(" select ");
sb.append(" DH1.ORDER_NO, ");
sb.append(" DH1.SHIPPER_CODE , ");
sb.append(" DH1.VEHICLE_NAME, ");
sb.append(" DH1.VEHICLE_CODE , ");
sb.append(" DH1.REASON_NAME_MOBILE, ");
sb.append(" DH1.STATUS_NAME_MOBILE ");
sb.append(" from ");
sb.append(" DELIVERY_HISTORY dh1 , ");
sb.append(" (select SHIPPER_CODE,ORDER_NO,max(UPDATED_DATETIME) as utime from DELIVERY_HISTORY ");
sb.append(" group by SHIPPER_CODE,ORDER_NO) dh2 ");
sb.append(" where ");
sb.append(" dh1.SHIPPER_CODE=dh2.SHIPPER_CODE and ");
sb.append(" dh1.ORDER_NO=dh2.ORDER_NO and ");
sb.append(" dh1.UPDATED_DATETIME=dh2.utime and ");
sb.append(" dh1.DISABLED_FLG='0' ");
String sql = sb.toString();
return sql;
}
private String getNewInnerSql() {
StringBuilder sb = new StringBuilder();
sb.append(" select ");
sb.append(" a.ORDER_NO, ");
sb.append(" a.SHIPPER_CODE , ");
sb.append(" a.VEHICLE_NAME, ");
sb.append(" a.VEHICLE_CODE , ");
sb.append(" a.REASON_NAME_MOBILE, ");
sb.append(" a.STATUS_NAME_MOBILE ,");
sb.append(" a.UPDATED_DATETIME");
sb.append(" from DELIVERY_HISTORY a");
sb.append(" where not exists(select 1 ");
sb.append(" from DELIVERY_HISTORY b");
sb.append(" where b.SHIPPER_CODE=a.SHIPPER_CODE and b.ORDER_NO=a.ORDER_NO and b.UPDATED_DATETIME>a.UPDATED_DATETIME)");
sb.append(" and a.DISABLED_FLG=0 ");
String sql = sb.toString();
return sql;
}
// test leftjoin plan
private boolean testLeftJoin(Statement stmt) throws SQLException {
StringBuilder sb = new StringBuilder();
sb.append(" SELECT ");
sb.append(" DH1.ORDER_NO, ");
sb.append(" DH1.SHIPPER_CODE ");
sb.append(" from ");
sb.append(" DELIVERY_HISTORY DH1 ");
sb.append(" left JOIN DELIVERY_HISTORY DH2 on ");
sb.append(" DH1.SHIPPER_CODE = DH2.SHIPPER_CODE ");
sb.append(" and DH1.ORDER_NO = DH2.ORDER_NO ");
sb.append(" and DH2.UPDATED_DATETIME > DH1.UPDATED_DATETIME ");
sb.append(" where DH2.UPDATED_DATETIME IS NULL ");
sb.append(" and DH1.DISABLED_FLG = 0 ");
String sql = sb.toString();
long startMs = System.currentTimeMillis();
stmt.executeQuery(sql);
long endMs = System.currentTimeMillis();
log.info("It takes "+ms2DHMS(startMs,endMs)+" to run leftjoin plan.");
log.info("Got " + toEastNumFormat(evaluateCntinSql(sql,stmt)) + " records after running leftjoin.");
return true;
}
// test innerjoin plan
private boolean testInnerJoin(Statement stmt) throws SQLException {
StringBuilder sb = new StringBuilder();
sb.append(" select ");
sb.append(" a.ORDER_NO, ");
sb.append(" a.SHIPPER_CODE ");
//sb.append(" a.VEHICLE_NAME, ");
//sb.append(" a.VEHICLE_CODE , ");
//sb.append(" a.REASON_NAME_MOBILE, ");
//sb.append(" a.STATUS_NAME_MOBILE ,");
//sb.append(" a.UPDATED_DATETIME");
sb.append(" from DELIVERY_HISTORY a");
sb.append(" where not exists(select 1 ");
sb.append(" from DELIVERY_HISTORY b");
sb.append(" where b.SHIPPER_CODE=a.SHIPPER_CODE and b.ORDER_NO=a.ORDER_NO and b.UPDATED_DATETIME>a.UPDATED_DATETIME)");
sb.append(" and a.DISABLED_FLG=0 ");
String sql = sb.toString();
long startMs = System.currentTimeMillis();
stmt.executeQuery(sql);
long endMs = System.currentTimeMillis();
log.info("It takes "+ms2DHMS(startMs,endMs)+" to run inner join plan.");
log.info("Got " + toEastNumFormat(evaluateCntinSql(sql,stmt)) + " records after running inner join.");
return true;
}
// evaluate how many records int resultset after running a sql
private long evaluateCntinSql(String sql,Statement stmt) throws SQLException {
String sql2 = "select count(*) as cnt from ("+sql+") ";
ResultSet rs = stmt.executeQuery(sql2);
while (rs.next()) {
int cnt = rs.getInt("cnt");
return cnt;
}
return 0;
}
// query how many records in table delivery_history
private boolean queryTotalCntinDH(Statement stmt) throws SQLException {
String sql = "select count(*) as cnt from delivery_history";
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
int cnt = rs.getInt("cnt");
log.info("There are " + toEastNumFormat(cnt) + " records in the table:'delivery_history'.");
}
return true;
}
// 将整数在万分位以逗号分隔表示
public static String toEastNumFormat(long number) {
DecimalFormat df = new DecimalFormat("#,####");
return df.format(number);
}
/**
* change seconds to DayHourMinuteSecond format
*
* @param startMs
* @param endMs
* @return
*/
private static String ms2DHMS(long startMs, long endMs) {
String retval = null;
long secondCount = (endMs - startMs) / 1000;
String ms = (endMs - startMs) % 1000 + "ms";
long days = secondCount / (60 * 60 * 24);
long hours = (secondCount % (60 * 60 * 24)) / (60 * 60);
long minutes = (secondCount % (60 * 60)) / 60;
long seconds = secondCount % 60;
if (days > 0) {
retval = days + "d" + hours + "h" + minutes + "m" + seconds + "s";
} else if (hours > 0) {
retval = hours + "h" + minutes + "m" + seconds + "s";
} else if (minutes > 0) {
retval = minutes + "m" + seconds + "s";
} else {
retval = seconds + "s";
}
return retval + ms;
}
public static String toMD5(String key) {
char hexDigits[] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
try {
byte[] btInput = key.getBytes();
// 获得MD5摘要算法的 MessageDigest 对象
MessageDigest mdInst = MessageDigest.getInstance("MD5");
// 使用指定的字节更新摘要
mdInst.update(btInput);
// 获得密文
byte[] md = mdInst.digest();
// 把密文转换成十六进制的字符串形式
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
return null;
}
}
}
--END-- 2019-12-20 18:26
SqlComparison的更多相关文章
- 2. MongoDB基本操作 —— 用Mongo.exe操作数据库增删改查
一.开篇 传统的关系数据库一般由数据库(database).表(table).记录(record)三个层次概念组成,MongoDB是由数据库(database).集合(collection).文档对象 ...
- CentOS MongoDB 高可用实战
原文:https://www.sunjianhua.cn/archives/centos-mongodb.html 一.MongoDB 单节点 1.1.Windows 版安装 1.1.1 获取社区版本 ...
- 170504、MongoDB和MySQL对比(译)
一.概要 几十年来,关系型数据库已经成为企业应用程序的基础,自从MySQL在1995年发布以来,它已经成为一种受欢迎并且廉价的选择.然而随着近年来数据量和数据的不断激增,非关系数据库技术如MongoD ...
- urlx
2015-09-24 23:41:26 centos6.6下安装MongoDB3.0.1 https://www.percona.com/doc/percona-tokumx/installation ...
- Node.js 操作Mongodb
Node.js 操作Mongodb1.简介官网英文文档 https://docs.mongodb.com/manual/ 这里几乎什么都有了MongoDB is open-source docum ...
- SQL to MongoDB Mapping Chart
http://docs.mongodb.org/manual/reference/sql-comparison/ In addition to the charts that follow, you ...
- MongoDB 走马观花(全面解读篇)
目录 一.简介 二.基本模型 BSON 数据类型 分布式ID 三.操作语法 四.索引 索引特性 索引分类 索引评估.调优 五.集群 分片机制 副本集 六.事务与一致性 一致性 小结 一.简介 Mong ...
- 了解 MongoDB 看这一篇就够了【华为云技术分享】
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...
- 了解 MongoDB 看这一篇就够了【华为云分享】
目录 一.简介 二.基本模型 BSON 数据类型 分布式ID 三.操作语法 四.索引 索引特性 索引分类 索引评估.调优 五.集群 分片机制 副本集 六.事务与一致性 一致性 小结 一.简介 Mong ...
随机推荐
- Android源码分析(四)-----Android源码编译及刷机步骤
一 : 获取源码: 每个公司服务器地址不同,以如下源码地址为例: http://10.1.14.6/android/Qualcomm/msm89xx/branches/msm89xx svn环境执行: ...
- Python 栈、队列的实现
在python中,列表既可以作为栈使用,又可以作为队列使用. 把列表作为栈使用 栈:后进先出 stack=[1,2,3] stack.append(4) #入栈,以列表尾部为栈顶 print(stac ...
- 使用DocumentFormat.OpenXml操作Excel文件.xlsx
1.开始 DocumentFormat.OpenXml是ms官方给一个操作office三大件新版文件格式(.xlsx,.docx,.pptx)的组件:特色是它定义了OpenXml所包含的所有对象(たぶ ...
- SpringBoot2.x的Maven依赖配置
本篇主要说明以下内容: 1.SpringBoot2.x中Maven的配置内容,即:pom.xml的内容说明 1 Maven依赖的配置方式 使用Maven来配置SpringBoot2.x,有两种方式: ...
- etcd和flannel实现docker跨物理机通信
实验目标 跨物理机的容器之间能直接访问docker通过Flannel可以实现各容器间的相互通信,即宿主机和容器,容器和容器之间都能相互通信 实验环境 192.168.3.50 //etcd.flann ...
- Shell 编程 条件语句
本篇主要写一些shell脚本条件语句的使用. 条件测试 test 条件表达式 [ 条件表达式 ] 文件测试 -d:测试是否为目录(Directory). -e:测试文件或目录是否存在(Exist). ...
- 阿里云ECS-使用putty产品psftp工具上传下载
本人windows10,安装了winscp3,原本可以简单易用,但天空不作美,死活不让我连接,无奈,只能换命令行方式, 好在,putty提供了一个小工具,psftp,不过,需要去官网下载完整版才有哦, ...
- 性能测试基础---LR参数化相关
性能测试脚本的增强:·参数化·关联·事务·检查点·思考时间·集合点 ·参数化:模拟不同用户的不同请求. ·为什么要做参数化? ·功能:通常来说,系统的某些业务数据具有唯一性的要求. ·性能:一般来说, ...
- mocker-api 原理
项目网址:https://github.com/jaywcjlove/mocker-api 作用有2个: 运行dev命令后,访问本地开启服务接口,模拟数据: 访问本机接口时,代理到其它服务器,即调用其 ...
- 31、Python程序中的协程操作(greenlet\gevent模块)
一.协程介绍 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的. 对比操作系统控制线程的切换,用 ...