zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    python高阶函数——返回函数(闭包)
    python高阶函数——sorted排序算法
    python高阶函数—filter
    python高阶函数——map/reduce
    Python——高阶函数概念(Higher-order function)
    Python高级特性——迭代器
    Python高级特性——生成器(generator)
    Python高级特性——列表生成式(list Comprehensions)
    Python高级特性——迭代(Iteration)
    Python高级特性——切片(Slice)
  • 原文地址:https://www.cnblogs.com/heyang78/p/12074263.html
Copyright © 2011-2022 走看看