利用JDBC和Oracle数据库的连接建立药品疫苗应用系统索引测试

一.需求分析

  • 使用VC/C++等程序设计语言以及与SQL(ORACLE)的接口编写一个有关药品疫苗应用系统。该系统涉及的关系模式有:

1.BS_BACTERIN_INFO (int 疫苗ID, String 疫苗编码, String 疫苗名称, int 疫苗种类, String 有效期, String 上市时间, String 上市地点);

2.BS_BACTERIN_PRICE(int 疫苗ID, int 厂家ID, int 上市价格, int 销售价格);

3.BS_MANUFACT(int 厂家ID, String 产商简称, String 产商全称, String 备注);

4.BS_PROVIDER(int 供应商ID, String 供应商名称, String 供应商地址, String 备注);

5.RT_PUTINSTORE_MAIN(int 供应商ID, int 确认, date 入库日期, String 采购员);

6.RT_PUTINSTORE_SUB(int SERIALNUMBER, int 疫苗ID, int 厂家ID, String 疫苗编码, date 有效期, int 销售价格, int 上市价格, int 入库数量, date 入库日期, String 发票号, int 疫苗种类, int 销售金额, int 应付账款, int 预付账款, String 上市名称, String 上市地点);

7.RT_PUTOUTSTORE_MAIN(int 确认, date 出库日期, String 提货人员, String 发票号);

8.RT_PUTOUTSTORE_SUB(int SERIALNUMBER, int 疫苗ID, int 厂家ID, String 疫苗编码, date 有效期, int 销售价格, int 上市价格, int 出库数量, int 疫苗种类, int 上市金额, int 销售金额, int 应付账款, String 发票号);

9.RT_STORE(int 疫苗ID, int 厂家ID, String 疫苗编码, date 有效期, int 上市数量, date 上市日期, int 上市价格, int 销售价格, int 销售金额);

10.RT_STORE_SORT(int 上市数量, int 上市金额, int 销售金额).

  • 该系统要求完成的功能:

    1.创建索引(一般索引、唯一性索引)。

    2.给出一个涉及索引属性的查询访问。循环执行该查询20次,显示执行时间。

    3.删除上一题查询访问涉及的索引,再重复执行该查询20次,显示执行时间。

    4.修改上两个题目中的查询为多表查询,在重复有索引和无索引时的执行情况。如果时间比较区分不出来,增加循环执行次数。

    5.其他任何你愿意做的与性能有关的讨论及实验。

二.Oracle数据库建表及插入数据

1.利用PL/SQL连接Oracle数据库,通过右键点击文件目录下的Tables项,可视化地建立新表,建立关系模式中涉及的10张表。对应的所有建表SQL语句如下:

create table BS_BACTERIN_INFO
(
  疫苗id NUMBER not null,
  疫苗编码 VARCHAR2(30),
  疫苗名称 VARCHAR2(100) not null,
  疫苗种类 NUMBER,
  有效期  VARCHAR2(30),
  上市名称 VARCHAR2(50),
  上市地点 VARCHAR2(50)
)
create table BS_BACTERIN_PRICE
(
  疫苗id NUMBER not null,
  厂家id NUMBER not null,
  上市价格 NUMBER(12,4),
  销售价格 NUMBER(12,4)
)
create table BS_MANUFACT
(
  厂家id NUMBER not null,
  产商简称 VARCHAR2(30),
  产商全称 VARCHAR2(100),
  备注   VARCHAR2(100)
)
create table BS_PROVIDER
(
  供应商id NUMBER not null,
  供应商名称 VARCHAR2(100) not null,
  供应商地址 VARCHAR2(100),
  备注    VARCHAR2(100)
)
create table RT_PUTINSTORE_MAIN
(
  供应商id NUMBER,
  确认    NUMBER(1) not null,
  入库日期  DATE,
  采购员   VARCHAR2(10)
)
create table RT_PUTINSTORE_SUB
(
  serialnumber NUMBER(18) not null,
  疫苗id         NUMBER not null,
  厂家id         NUMBER not null,
  疫苗编码         VARCHAR2(50),
  有效期          DATE,
  销售价格         NUMBER(12,4) not null,
  上市价格         NUMBER(12,4) not null,
  入库数量         NUMBER(12,4) not null,
  入库日期         DATE,
  发票号          VARCHAR2(30),
  疫苗种类         NUMBER(6),
  销售金额         NUMBER(12,4) not null,
  应付账款         NUMBER(12,2),
  预付账款         NUMBER(12,2),
  上市名称         VARCHAR2(10),
  上市地点         VARCHAR2(10)
)
create table RT_PUTOUTSTORE_MAIN
(
  确认   NUMBER(1) not null,
  出库日期 DATE,
  提货人员 VARCHAR2(10),
  发票号  VARCHAR2(10)
)
create table RT_PUTOUTSTORE_SUB
(
  serialnumber NUMBER(18) not null,
  疫苗id         NUMBER not null,
  厂家id         NUMBER not null,
  疫苗编码         VARCHAR2(10),
  有效期          DATE,
  销售价格         NUMBER(12,4) not null,
  上市价格         NUMBER(12,4),
  出库数量         NUMBER(10,2) not null,
  疫苗种类         NUMBER(6),
  上市金额         NUMBER(12,4) not null,
  销售金额         NUMBER(12,4) not null,
  应付账款         NUMBER(12,4),
  发票号          VARCHAR2(10)
)
create table RT_STORE
(
  疫苗id NUMBER not null,
  厂家id NUMBER not null,
  疫苗编码 VARCHAR2(10),
  有效期  DATE,
  上市数量 NUMBER(10,2) not null,
  上市日期 DATE,
  上市价格 NUMBER(12,4) not null,
  销售价格 NUMBER(12,4) not null,
  销售金额 NUMBER(12,4)
)
create table RT_STORE_SORT
(
  上市数量 NUMBER(10,2) not null,
  上市金额 NUMBER(12,4) not null,
  销售金额 NUMBER(12,4) not null
)

2.将Excel表中的数据批量导入数据库各表中,具体方法为在PL/SQL中右键点击要导入数据的表的编辑数据菜单,将光标点到空白表项中,然后拖动鼠标连选表的所有字段,再将Excel中复制的剪贴板中的数据粘贴到数据库中。检查各字段的值是否有违反字段类型的,检查无误后,选择PL/SQL的左上角的Commit工具,提交事务。直至将所有表的数据全部导入。

三.利用JDBC连接数据库并通过界面输出查询时间

JDBC是java数据库连接的API,主要位于JDK中的java.sql包中,扩展的内容位于javax.sql包中。其作用为:与一个数据库建立连接、向数据库发送SQL语句、处理数据库返回的结果。

1.装载JDBC驱动程序:

在Oracle数据库安装文件夹中找到jdbc文件夹→lib文件夹→ojdbc6.jar→导入项目的库中。

2.测试与数据库的连接:

9

3.确定需要建立的索引:

--对表RT_PUTINSTORE_SUB的查询语句
select * from RT_PUTINSTORE_SUB where 疫苗ID=1 and SerialNumber=25;
--对表RT_PUTINSTORE_SUB建立字段SerialNumber的普通索引
create index rtputin_sub_serialnum on RT_PUTINSTORE_SUB(SerialNumber);
--删除表RT_PUTINSTORE_SUB建立字段SerialNumber的普通索引
drop index rtputin_sub_serialnum;
--对表RT_PUTINSTORE_SUB建立字段疫苗ID和字段SerialNumber的唯一性索引
create unique index unique_rtputin_sub_serialnum on RT_PUTINSTORE_SUB(疫苗ID,SerialNumber);
--删除表RT_PUTINSTORE_SUB建立的唯一性索引
drop index unique_rtputin_sub_serialnum;

--对表RT_PUTINSTORE_SUB和表RT_PUTOUTSTORE_SUB的多表查询语句
select * from RT_PUTINSTORE_SUB,RT_PUTOUTSTORE_SUB where RT_PUTOUTSTORE_SUB.SerialNumber=RT_PUTINSTORE_SUB.SerialNumber and RT_PUTOUTSTORE_SUB.疫苗ID=2;
--对表RT_PUTOUTSTORE_SUB建立字段SerialNumber的普通索引
create index rtputout_sub_serialnum on RT_PUTOUTSTORE_SUB(SerialNumber);
--删除表RT_PUTOUTSTORE_SUB建立字段SerialNumber的普通索引
drop index rtputout_sub_serialnum;
--对表RT_PUTOUTSTORE_SUB建立字段SerialNumber和字段疫苗ID的唯一性索引
create unique index unique_rtputout_sub_serialnum on RT_PUTOUTSTORE_SUB(SerialNumber,疫苗ID);
--删除表RT_PUTOUTSTORE_SUB建立的唯一性索引
drop index unique_rtputout_sub_serialnum;
--对表RT_PUTINSTORE_SUB建立字段SerialNumber和字段疫苗ID的唯一性索引
create unique index unique_rtputin_sub on RT_PUTINSTORE_SUB(SerialNumber,疫苗ID);
--删除表RT_PUTINSTORE_SUB建立的唯一性索引
drop index unique_rtputin_sub;

4.利用Java的Swing组件建立药品疫苗应用系统的索引测试界面:

/*
 * 药品疫苗应用系统索引测试
 * @author:sily
 * create at 2017.5.21
 */

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.UnsupportedEncodingException;
import java.sql.*;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;

public class bacterin extends JFrame {

    private static final long serialVersionUID = -2270569976296891899L;
    private static String url = "jdbc:oracle:thin:@localhost:1521:orcl";
    private static String user="system";
    private static String password = "test";
    public static Connection conn;
    public static PreparedStatement ps;
    public static ResultSet rs;
    public static Statement st;
    //单表查询
    private static String query_rt_putin_sub = "select * from RT_PUTINSTORE_SUB where 疫苗ID=1 and SerialNumber=25";
    private static String index_rt_putin_sub = "create index rtputin_sub_serialnum on RT_PUTINSTORE_SUB(SerialNumber)";
    private static String delete_index_rt_putin_sub = "drop index rtputin_sub_serialnum";
    private static String unique_index_rt_putin_sub = "create unique index unique_rtputin_sub_serialnum on RT_PUTINSTORE_SUB(疫苗ID,SerialNumber)";
    private static String delete_unique_index_rt_putin_sub = "drop index unique_rtputin_sub_serialnum";
    //多表查询
    private static String query_putin_putout_sub = "select * from RT_PUTINSTORE_SUB,RT_PUTOUTSTORE_SUB "
            + "where RT_PUTOUTSTORE_SUB.SerialNumber=RT_PUTINSTORE_SUB.SerialNumber and RT_PUTOUTSTORE_SUB.疫苗ID=2";
    //多表查询的一般索引
    private static String index_rt_putout_sub = "create index rtputout_sub_serialnum on RT_PUTOUTSTORE_SUB(SerialNumber)";
    private static String delete_index_rt_putout_sub = "drop index rtputout_sub_serialnum";
    //多表查询建立的唯一性索引
    private static String unique_index_rt_putout_sub = "create unique index unique_rtputout_sub_serialnum on RT_PUTOUTSTORE_SUB(SerialNumber,疫苗ID)";
    private static String unique_index_rt_putin = "create unique index unique_rtputin_sub on RT_PUTINSTORE_SUB(SerialNumber,疫苗ID)";
    private static String delete_unique_index_rt_putout_sub = "drop index unique_rtputout_sub_serialnum";
    private static String delete_unique_index_rt_putin = "drop index unique_rtputin_sub";
    //显示查询时间信息的标签
    static JPanel panel = new JPanel();
    static JLabel JLabel1 = new JLabel();
    static JLabel JLabel2 = new JLabel();
    static JLabel JLabel3 = new JLabel();
    static JLabel JLabel4 = new JLabel();
    static JLabel JLabel5 = new JLabel();
    static JLabel JLabel6 = new JLabel();
    static JLabel JLabel7 = new JLabel();
    static JLabel JLabel8 = new JLabel();
    static JLabel JLabel9 = new JLabel();
    static JLabel JLabel10 = new JLabel();
    static JLabel JLabel11= new JLabel();
    static JLabel JLabel12 = new JLabel();
    static JLabel JLabel13 = new JLabel();
    //类的构造方法
    public bacterin(){
        this.init();        //初始化,绘制界面
    }
    public void init(){
        this.setTitle("疫苗应用系统索引测试");
        this.setBounds(100,100,340,500);
        this.createUI();    //绘制界面的方法
        this.setVisible(true);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    public void createUI(){

        Border border = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
        TitledBorder tBorder = BorderFactory.createTitledBorder(border,"查询面板",TitledBorder.CENTER
                ,TitledBorder.TOP); 
        panel.setBorder(tBorder);
        panel.setLayout(null);
        this.add(panel);
        JButton btn = new JButton("查询并显示结果");       //添加查询按钮
        btn.setBounds(80, 50, 150, 22);
        btn.addActionListener(new ActionListener(){     //按钮的点击事件
            public void actionPerformed(ActionEvent arg0){
                test(query_rt_putin_sub);           //查询前的第一次缓冲测试
                System.out.println("未建立任何索引:"); 
                JLabel1.setBounds(50, 90, 300, 100);
                panel.add(JLabel1);
                JLabel1.setText("未建立任何索引");

                JLabel2.setBounds(50, 100, 300, 100);
                panel.add(JLabel2);                 //未建立索引的查询
                JLabel2.setText("查询执行时间: " + query(query_rt_putin_sub,2000) + "ms");

                System.out.println("\n建立一般索引:");
                createIndex(index_rt_putin_sub);
                JLabel3.setBounds(50, 120, 300, 100);
                panel.add(JLabel3);
                JLabel3.setText("建立一般索引");
                JLabel4.setBounds(50, 130, 300, 100);
                panel.add(JLabel4);                 //建立一般索引后的查询
                JLabel4.setText("查询执行时间: " + query(query_rt_putin_sub,2000) + "ms");
                deleteIndex(delete_index_rt_putin_sub);

                System.out.println("\n建立唯一性索引:");
                createIndex(unique_index_rt_putin_sub);
                JLabel5.setBounds(50, 150, 300, 100);
                panel.add(JLabel5);
                JLabel5.setText("建立唯一性索引");
                JLabel6.setBounds(50, 160, 300, 100);
                panel.add(JLabel6);                 //建立唯一性索引后的查询
                JLabel6.setText("查询执行时间: " + query(query_rt_putin_sub,2000) + "ms");
                deleteIndex(delete_unique_index_rt_putin_sub);
                //多表查询
                System.out.println("\n多表查询:");
                JLabel7.setBounds(50, 180, 300, 100);
                panel.add(JLabel7);
                JLabel7.setText("多表查询");
                test(query_putin_putout_sub);   //查询前的第一次缓冲测试

                System.out.println("\n未建立任何索引:");
                JLabel8.setBounds(50, 190, 300, 100);
                panel.add(JLabel8);
                JLabel8.setText("未建立任何索引");
                JLabel9.setBounds(50, 200, 300, 100);
                panel.add(JLabel9);             //未建立索引的查询
                JLabel9.setText("查询执行时间: " + query(query_putin_putout_sub,1000) + "ms");

                System.out.println("\n建立一般索引:");
                createIndex(index_rt_putin_sub);
                createIndex(index_rt_putout_sub);
                JLabel10.setBounds(50, 220, 300, 100);
                panel.add(JLabel10);
                JLabel10.setText("建立一般索引");
                JLabel11.setBounds(50, 230, 300, 100);
                panel.add(JLabel11);            //建立一般索引后的查询
                JLabel11.setText("查询执行时间: " + query(query_putin_putout_sub,1000) + "ms");
                deleteIndex(delete_index_rt_putin_sub);
                deleteIndex(delete_index_rt_putout_sub);

                System.out.println("\n建立唯一性索引:");
                createIndex(unique_index_rt_putout_sub);
                createIndex(unique_index_rt_putin);
                JLabel12.setBounds(50, 250, 300, 100);
                panel.add(JLabel12);
                JLabel12.setText("建立唯一性索引");
                JLabel13.setBounds(50, 260, 300, 100);
                panel.add(JLabel13);            //建立唯一性索引后的查询
                JLabel13.setText("查询执行时间: " + query(query_putin_putout_sub,1000) + "ms");
                deleteIndex(delete_unique_index_rt_putout_sub);
                deleteIndex(delete_unique_index_rt_putin);
            }
        });
        panel.add(btn);

    }
    //利用DriverManager的getConnection方法建立的连接数据库的URL对象
    public static void getConnection(){         
        try{
            Class.forName("oracle.jdbc.driver.OracleDriver");
            conn = DriverManager.getConnection(url, user, password);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    //查询SQL语句的方法,循环执行上千次查询语句,返回查询所用的总时间
    public static long query(String query,int time){
        long startTime=0,endTime=0;
        getConnection();
        if(conn == null){
            System.out.println("与oracle数据库连接失败!");
        }else{
        //  System.out.println("与oracle数据库连接成功!");
        }
        try {
            startTime = System.currentTimeMillis(); // 获取开始时间

            for(int i=0; i<time; i++){

                st = conn.createStatement();
                rs = st.executeQuery(query);
            while(rs.next()){
                //打印输出查询结果,在此省略
//              System.out.println(((rs.getString(1)) != null?rs.getString(1):"-") + "\t"
//                      + ((rs.getString(2)) != null?rs.getString(2):"-" )+ "\t"
//                      + ((rs.getString(3)) != null?rs.getString(3):"-" )+ "\t"
//                  );

            }
            rs.close();
            }
            endTime = System.currentTimeMillis(); // 获取结束时间  
             System.out.println("查询执行时间: " + (endTime - startTime) + "ms"); 

             conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return (endTime - startTime);
    }
    //第一次循环前的测试数据库缓冲,以获得稳定的查询时间
    public static void test(String query){
        getConnection();
        try {
            for(int i=0; i<200; i++){
                st = conn.createStatement();
                rs = st.executeQuery(query);
            while(rs.next()){

            }
            rs.close();
            }
             conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    //创建索引的方法
    public static void createIndex(String index){
        getConnection();
        try {
            st = conn.createStatement();
            st.execute(index);
            conn.close();
        } catch (SQLException e1) {
            // TODO 自动生成的 catch 块
            e1.printStackTrace();
        }
        System.out.println("索引已建立!");
    }

    //删除索引的方法
    public static void deleteIndex(String index){
        getConnection();
        try {
            st = conn.createStatement();
            st.execute(index);
            conn.close();
        } catch (SQLException e1) {
            // TODO 自动生成的 catch 块
            e1.printStackTrace();
        }
        System.out.println("索引已删除!");
    }
    //main主函数,注释掉的语句为未使用Swing组件前的查询,通过控制台输出查询时间
    public static void main(String[] args) throws UnsupportedEncodingException{

        new bacterin();
    //  test(query_rt_putin_sub);
/*      System.out.println("未建立任何索引:");
        query(query_rt_putin_sub,2000);
        System.out.println("\n建立一般索引:");
        createIndex(index_rt_putin_sub);
        query(query_rt_putin_sub,2000);
        deleteIndex(delete_index_rt_putin_sub);
        System.out.println("\n建立唯一性索引:");
        createIndex(unique_index_rt_putin_sub);
        query(query_rt_putin_sub,2000);
        deleteIndex(delete_unique_index_rt_putin_sub);

        System.out.println("\n多表查询:");
        System.out.println("未建立任何索引:");
    //  test(query_putin_putout_sub);
        query(query_putin_putout_sub,1000);
        System.out.println("\n建立一般索引:");
    //  createIndex(index_rt_putin_sub);
        createIndex(index_rt_putout_sub);
        query(query_putin_putout_sub,1000);
    //  deleteIndex(delete_index_rt_putin_sub);
        deleteIndex(delete_index_rt_putout_sub);
        System.out.println("\n建立唯一性索引:");
    //  createIndex(unique_index_rt_putin_sub);
        createIndex(unique_index_rt_putout_sub);
        query(query_putin_putout_sub,1000);
    //  deleteIndex(delete_unique_index_rt_putin_sub);
        deleteIndex(delete_unique_index_rt_putout_sub); */

    }
}

四.查询结果

  • 界面输出结果如下:

10

  • 在单表查询中,查询的表为RT_PUTINSTORE_SUB,查询的语句为:

    select * from RT_PUTINSTORE_SUB where 疫苗ID=1 and SerialNumber=25;

    这个表共有1226条数据,循环执行该查询2000次,未建立任何索引得到的查询时间为821ms;

    建立一般索引后:

    create index rtputin_sub_serialnum on RT_PUTINSTORE_SUB(SerialNumber);

    查询时间减少到564ms;

    建立唯一性索引后:

    create unique index unique_rtputin_sub_serialnum on RT_PUTINSTORE_SUB(疫苗ID,SerialNumber);

    查询时间减少到477ms。

由此可见建立索引后可大大加快涉及索引项的查询。

  • 在多表查询中,查询的表为RT_PUTINSTORE_SUB和RT_PUTOUTSTORE_SUB,查询的语句为:

    select * from RT_PUTINSTORE_SUB,RT_PUTOUTSTORE_SUB where RT_PUTOUTSTORE_SUB.SerialNumber=RT_PUTINSTORE_SUB.SerialNumber and RT_PUTOUTSTORE_SUB.疫苗ID=2;

    表RT_PUTINSTORE_SUB的数据有1226条,表RT_PUTOUTSTORE_SUB的数据共有5504条,循环执行该查询1000次,未建立任何索引得到的查询时间为718ms;

    对两张表均建立一般索引后:

    create index rtputin_sub_serialnum on RT_PUTINSTORE_SUB(SerialNumber);

    create index rtputout_sub_serialnum on RT_PUTOUTSTORE_SUB(SerialNumber);

    查询时间减少到572ms;

    对两张表均建立唯一性索引后:

    create unique index unique_rtputout_sub_serialnum on RT_PUTOUTSTORE_SUB(SerialNumber,疫苗ID);

    create unique index unique_rtputin_sub on RT_PUTINSTORE_SUB(SerialNumber,疫苗ID);

    查询时间减少到409ms。

    结论与单表查询一致。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页