统计总数的三种处理方式(SQL,JDBC,PROCEDUER)

1、最快的方式,一条SQL执行完毕(耗时92.266S):

SELECT COUNT(DV.DEVICE_ID)
  FROM PROD_FUNCTION_LOCATION FL,
       PROD_FL_DEVICE FD,
       PROD_DEVICE DV,
       PUB_CLASSIFY CL,
       (SELECT FL.VOLTAGE_LEVEL, FL.FUNCTION_LOCATION_CODE
          FROM PROD_FUNCTION_LOCATION FL
         WHERE FL.FUNCTION_LOCATION_NAME LIKE '%kV电压等级区%'
           AND FL.VOLTAGE_LEVEL > 1000
           AND FL.COPY_FLAG = 0) TBL
 WHERE DV.DEVICE_ID = FD.DEVICE_ID
   AND DV.VOLTAGE_LEVEL != TBL.VOLTAGE_LEVEL
   AND FD.DEVICE_CLASSIFY_CODE = CL.ALIAS_NAME
   AND CL.CODE LIKE '0101%'
   AND FD.FUNCTION_LOCATION_ID = FL.FUNCTION_LOCATION_ID
   AND FL.COPY_FLAG = 0
   AND FL.FUNCTION_LOCATION_CODE LIKE TBL.FUNCTION_LOCATION_CODE || '-%';

 

 

2、稍慢的方式,通过JDBC实现(133S):

package test.batch;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import test.DBUtil;

public class VolCount {

    private List<VO1> getList() {
        StringBuffer sbSQL = new StringBuffer(200);
        sbSQL.append("SELECT FL.VOLTAGE_LEVEL, FL.FUNCTION_LOCATION_CODE");
        sbSQL.append("      FROM PROD_FUNCTION_LOCATION FL");
        sbSQL.append("     WHERE FL.FUNCTION_LOCATION_NAME LIKE '%kV电压等级区%'");
        sbSQL.append("       AND FL.VOLTAGE_LEVEL > 1000");
        sbSQL.append("       AND FL.COPY_FLAG = 0");
        List<VO1> values = new ArrayList<VO1>();
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            // 设置数据库连接
            conn = DBUtil.getConnection();
            stmt = conn.createStatement();
            rs = stmt.executeQuery(sbSQL.toString());
            VO1 vo = null;
            while (rs.next()) {
                vo = new VO1();
                vo.vol = rs.getInt(1);
                vo.code = rs.getString(2);
                values.add(vo);
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
        } finally {
            DBUtil.closeConnection(null, stmt, conn);
        }
        return values;
    }

    private int getSingleCount(int vol, String code) {
        StringBuffer sbSQL = new StringBuffer(411);
        sbSQL.append("SELECT COUNT(DV.DEVICE_ID)");
        sbSQL.append("  FROM PROD_FUNCTION_LOCATION FL,");
        sbSQL.append("       PROD_FL_DEVICE         FD,");
        sbSQL.append("       PROD_DEVICE            DV,");
        sbSQL.append("       PUB_CLASSIFY           CL");
        sbSQL.append(" WHERE DV.DEVICE_ID = FD.DEVICE_ID");
        sbSQL.append("   AND DV.VOLTAGE_LEVEL != ?");
        sbSQL.append("   AND FD.DEVICE_CLASSIFY_CODE = CL.ALIAS_NAME");
        sbSQL.append("   AND CL.CODE LIKE '0101%'");
        sbSQL.append("   AND FD.FUNCTION_LOCATION_ID = FL.FUNCTION_LOCATION_ID");
        sbSQL.append("   AND FL.COPY_FLAG = 0");
        sbSQL.append("   AND FL.FUNCTION_LOCATION_CODE LIKE ?");
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        int value = 0;
        try {
            // 设置数据库连接
            conn = DBUtil.getConnection();
            pstmt = conn.prepareStatement(sbSQL.toString());
            pstmt.setInt(1, vol);
            pstmt.setString(2, code+"-%");
            rs = pstmt.executeQuery();
            if (rs.next()) {
                value = rs.getInt(1);
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
        } finally {
            DBUtil.closeConnection(null, pstmt, conn);
        }
        return value;
    }

    class VO1 {

        int vol;

        String code;
    }

    public static void main(String[] args) {
        VolCount v = new VolCount();
        int total = 0;
        long time = System.currentTimeMillis();
        for(VO1 vo:v.getList()){
            total+=v.getSingleCount(vo.vol, vo.code);
        }
        System.out.println("total:"+total+" time:"+(System.currentTimeMillis()-time)/1000);
    }
}

 

3、最慢的方式,游标实现(在我的耐心范围内都没有出现结果):

 

CREATE OR REPLACE PROCEDURE P_DATA_AUDIT_DEV_VOL(DETAIL_ID  IN INTEGER,
                                                 COLLECT_ID IN INTEGER) IS
  V_TOTAL     INTEGER;
  V_TEMP      INTEGER;
  V_DETAIL_ID INTEGER;
  V_DATE      DATE;
  CURSOR C_OUTER IS
    SELECT FL.VOLTAGE_LEVEL, FL.FUNCTION_LOCATION_CODE
      FROM PROD_FUNCTION_LOCATION FL
     WHERE FL.FUNCTION_LOCATION_NAME LIKE '%kV电压等级区%'
       AND FL.VOLTAGE_LEVEL > 1000
       AND FL.COPY_FLAG = 0;

  CURSOR C_INNER(V_CODE VARCHAR2, V_VOL INTEGER) IS
    SELECT COUNT(DV.DEVICE_ID) COUNT
      FROM PROD_FUNCTION_LOCATION FL,
           PROD_FL_DEVICE         FD,
           PROD_DEVICE            DV,
           PUB_CLASSIFY           CL
     WHERE DV.DEVICE_ID = FD.DEVICE_ID
       AND DV.VOLTAGE_LEVEL != V_VOL
       AND FD.DEVICE_CLASSIFY_CODE = CL.ALIAS_NAME
       AND CL.CODE LIKE '0101%'
       AND FD.FUNCTION_LOCATION_ID = FL.FUNCTION_LOCATION_ID
       AND FL.COPY_FLAG = 0
       AND FL.FUNCTION_LOCATION_CODE LIKE V_CODE || '-%';
BEGIN
  V_TOTAL     := 0;
  V_TEMP      := 0;
  V_DETAIL_ID := DETAIL_ID;
  V_DATE      := SYSDATE;

  FOR O_REC IN C_OUTER LOOP
    FOR I_REC IN C_INNER(O_REC.FUNCTION_LOCATION_CODE, O_REC.VOLTAGE_LEVEL) LOOP
      DBMS_OUTPUT.PUT_LINE('COUNT'||I_REC.COUNT);
      V_DETAIL_ID := V_DETAIL_ID + I_REC.COUNT;      
    END LOOP;
  END LOOP;
  
  DBMS_OUTPUT.PUT_LINE('V_DETAIL_ID:' || V_DETAIL_ID || ' TIME:' ||
                       TO_NUMBER(SYSDATE - V_DATE) * 24 * 60 * 60 || 's');
EXCEPTION
  WHEN OTHERS THEN
    IF C_INNER%ISOPEN THEN
      CLOSE C_INNER;
    END IF;
    IF C_OUTER%ISOPEN THEN
      CLOSE C_OUTER;
    END IF;
END;
/

 

你可能感兴趣的:(sql,C++,c,jdbc,C#)