对于一万条数据量使用Oracle游标,存储过程,一般查询的速度的对比

一,创建ID自增长表格

1,创建序列

create sequence my_em_seq --序列名
     minvalue 1--最小值
     maxvalue 9999999999999999999999999999--最大值
     start with 1--起始值
     increment by 1--
     nocache;
     

2,创建触发器

create or replace trigger my_emp_add
before insert on my_emp--表名
     for each row
         begin
               select employ_autoinc.nextval into :new.Id from dual;

二,插入30000条数据

insert into my_emp(my_emp.name,my_emp.sal,my_emp.tele) values('aa',232,'123');
insert into my_emp(my_emp.name,my_emp.sal,my_emp.tele) select my_emp.name,my_emp.sal,my_emp.tele from my_emp

第一句话是插入一个数据第二句是插入自己原来表的数据

SQL> insert into my_emp(my_emp.name,my_emp.sal,my_emp.tele) values('aa',232,'123');
 
1 row inserted
 
SQL> insert into my_emp(my_emp.name,my_emp.sal,my_emp.tele) values('aasre',2452,'654523');
 
1 row inserted
 
SQL> insert into my_emp(my_emp.name,my_emp.sal,my_emp.tele) values('aare',252,'65423');
 
1 row inserted
 
SQL> insert into my_emp(my_emp.name,my_emp.sal,my_emp.tele) values('aafre',25652,'6523');
 
1 row inserted
 
SQL> insert into my_emp(my_emp.name,my_emp.sal,my_emp.tele) select my_emp.name,my_emp.sal,my_emp.tele from my_emp;
 
30 rows inserted
 
SQL> insert into my_emp(my_emp.name,my_emp.sal,my_emp.tele) select my_emp.name,my_emp.sal,my_emp.tele from my_emp;
 
60 rows inserted
 
SQL> insert into my_emp(my_emp.name,my_emp.sal,my_emp.tele) select my_emp.name,my_emp.sal,my_emp.tele from my_emp;
 
120 rows inserted
 
SQL> insert into my_emp(my_emp.name,my_emp.sal,my_emp.tele) select my_emp.name,my_emp.sal,my_emp.tele from my_emp;
 
240 rows inserted
 
SQL> insert into my_emp(my_emp.name,my_emp.sal,my_emp.tele) select my_emp.name,my_emp.sal,my_emp.tele from my_emp;
 
480 rows inserted
 
SQL> insert into my_emp(my_emp.name,my_emp.sal,my_emp.tele) select my_emp.name,my_emp.sal,my_emp.tele from my_emp;
 
960 rows inserted
 
SQL> insert into my_emp(my_emp.name,my_emp.sal,my_emp.tele) select my_emp.name,my_emp.sal,my_emp.tele from my_emp;
 
1920 rows inserted
 
SQL> 
SQL> insert into my_emp(my_emp.name,my_emp.sal,my_emp.tele) select my_emp.name,my_emp.sal,my_emp.tele from my_emp;
 
3840 rows inserted
 
SQL> insert into my_emp(my_emp.name,my_emp.sal,my_emp.tele) select my_emp.name,my_emp.sal,my_emp.tele from my_emp;
SQL> 
 
7680 rows inserted
 
SQL> insert into my_emp(my_emp.name,my_emp.sal,my_emp.tele) select my_emp.name,my_emp.sal,my_emp.tele from my_emp;
SQL> 
 
15360 rows inserted
 

三,使用一般处理程序加载数据

            string str = "select * from my_emp";
            List<date> list = new List<date>();
            OracleDataReader read = OracleHelper.ExecuteReader(CommandType.Text, str, null);
            while (read.Read()) {
                date name = new date();
                name.id = read.GetInt32(0);
                name.name=read.GetString(1);
                name.sal = read.GetInt32(2);
                name.tele = read.GetInt32(3);
                list.Add(name);
            }
            dataGridView1.DataSource = list;

耗时:初次5200ms,第二层200ms

四,使用游标加载数据

1,

--创建一个包,包中定义一个游标类型
create or replace package cursor1 is
       type my_cursor is ref cursor;
end;

2,编写存储过程

--编写过程
create or replace procedure my_emp_cursor(my_emp_cursor out cursor1.my_cursor) is
begin 
--打开游标 
       open my_emp_cursor for select * from my_emp ;
end;

3,编写存储过程程序

            string str = "my_emp_cursor";//存储过程名字
            List<date> list = new List<date>();

            OracleParameter para = new OracleParameter("my_emp_cursor", OracleDbType.RefCursor);//调用下面的参数
            para.Direction = ParameterDirection.Output;//设置参数
            DataTable tab=  OracleHelper.ExecuteOutParaNoParam(str, para);
            dataGridView1.DataSource = tab;
 public static DataTable ExecuteOutParaNoParam(string str, OracleParameter param)
        {
            OracleConnection oc = new OracleConnection(connectionString);
            oc.Open();
            OracleCommand om = oc.CreateCommand();
            om.CommandType = CommandType.StoredProcedure;
            om.CommandText = str;
            om.Parameters.Add(param);

            om.ExecuteNonQuery();
            DataTable table = new DataTable();
            OracleDataAdapter da1 = new OracleDataAdapter(om);//取出数据
            da1.Fill(table);
            oc.Close();
            return table;
        }

测试结果:使用游标第一次 5600ms,第二次,600ms

对比结论:在查询数据过程中,一般处理的程序的速度比游标快。

稳定性总结:一次以每一秒点击一次的频率点击,以0.5s的频率点击

   两者的稳定性差不多

五.计算总和测试

1,使用一般处理程序计算3万个数据的总和

  DateTime beforDT = System.DateTime.Now;
            //耗时巨大的代码
            string str = "select * from my_emp";
            List<date> list = new List<date>();
            OracleDataReader read = OracleHelper.ExecuteReader(CommandType.Text, str, null);
            Int64 sum = 0;
            while (read.Read())
            {
                int a = 0;
                a = read.GetInt32(2);
                sum += a;
            }
            labelControl10.Text = sum.ToString();
            DateTime afterDT = System.DateTime.Now;
            TimeSpan ts = afterDT.Subtract(beforDT);
            labTime.Text = ts.TotalMilliseconds.ToString();

第一次消耗时间:4651ms,

第二次消耗时间,117ms,

当连续点击时可能出现卡顿,偶尔出现4700ms-1000ms左右的时间。

这部分时间主要用在连接数据库获取数据的时间,计算的时间稳定在114-117ms之间。剩下的是连接数据库将数据加载的内存中的时间

2,采用存储过程sum(*)计算

create or replace procedure jisuansum(salsum out number) is
begin
  select sum(sal) into salsum from my_emp;
end;

C#程序这么写

        string str = "jisuansum";
            OracleParameter para = new OracleParameter("salsum", OracleDbType.Int64);
            para.Direction = ParameterDirection.Output;
            OracleHelper.ExecuteOutParaNoParam(str,para);
            labelControl2.Text = para.Value.ToString();
ExecuteOutParaNoParam这么写
  public static DataTable ExecuteOutParaNoParam(string str, OracleParameter param)
        {
            OracleConnection oc = new OracleConnection(connectionString);
            oc.Open();
            OracleCommand om = oc.CreateCommand();
            om.CommandType = CommandType.StoredProcedure;
            om.CommandText = str;
            om.Parameters.Add(param);

            om.ExecuteNonQuery();
            DataTable table = new DataTable();
            OracleDataAdapter da1 = new OracleDataAdapter(om);//取出数据
            da1.Fill(table);
            oc.Close();
            return table;
        }

计算结果:第一次5091ms,

              第二次34ms,

     第三次17ms-19ms,之间

连续点击性能稳定一般在17-19ms之间,不会出现卡顿现象

2,采用存储过程游标计算

create or replace procedure jisuansum_cursor(sumsal out number) is
  cursor c_dept is select * from my_emp;  --声明游标C_dept属性
    type dept_record is table of c_dept%rowtype;  --定义游标的行dept_record属性
    v_dept dept_record; --定义行变量
   
begin
     sumsal:=0; --赋初值,必须要
    open c_dept;  --打开游标
    fetch c_dept bulk collect into v_dept;  --提取游标数据
    close c_dept;  
    for i in 1.. v_dept.count loop--循环提取数据  
        sumsal:=sumsal+v_dept(i).sal;   
    end loop;  
end;

 C# 程序

string str = "jisuansum_cursor";
            OracleParameter para = new OracleParameter("salsum", OracleDbType.Int64);
            para.Direction = ParameterDirection.Output;
            OracleHelper.ExecuteOutParaNoParam(str, para);
            labelControl14.Text = para.Value.ToString();

结果第一次5295ms

     第二次203ms

     第三次194ms,剩下的一般在这个范围之间

连续点击系统不会出现卡顿的现象

以上分析:对于数据的查看-----使用存储过程与游标会使系统更

              对于系统的计算与统计--使用存储过程会使系统更稳定

           如果使用Oracle自带的函数--会使系统速度提高很多,

             如果没有速度比一般处理程序慢,两者的计算速度都比较快,基本不影响用户体验

综上:使用存储过程会使系统更加稳定。

 程序在此下载

:http://download.csdn.net/download/quankangquan/9825214

 

 

 

posted @ 2017-04-24 11:03  Restrain  阅读(5545)  评论(0编辑  收藏  举报