对于一万条数据量使用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