设为首页 收藏本站
查看: 878|回复: 0

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

[复制链接]

尚未签到

发表于 2017-12-11 07:34:44 | 显示全部楼层 |阅读模式
  一,创建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
  

  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-422849-1-1.html 上篇帖子: 利用Powerdesigner16.5(64位)连接64位oracle 配置系统odbc驱动 下篇帖子: oracle11g 重装操作系统后,如何利用原有oracle表空间文件还原数据库
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表