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

摘要:
1、 创建ID自增长表1并创建序列createsequencemy_em_Seq--序列名称minvalue1--最小maxvalue99999999999999999999--最大startwith1--起始值递增1--步长nocache;2.创建触发器createorplacetriggery_emp_addbeforeinsertony_emp-table

一,创建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

 

免责声明:文章转载自《对于一万条数据量使用Oracle游标,存储过程,一般查询的速度的对比》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Idea 中的快捷键(mac)EBS年底定义sequence以及assign的相关操作下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

[转]Oracle中使用Rownum分页详细例子

原文地址:http://www.jb51.net/article/52272.htm 在MySQL中,我们通常都使用limit来完成数据集获取的分页操作,而在Oracle数据库中,并没有类似limit一样的方便方法来实现分 页,因此我们通常都是直接在SQL语句中完成分页,这里就需要借助于rownum伪列或row_number()函数了,本文将分别展示使用...

数据安全:通过Oracle的基本函数实现简单加密脱敏函数

注我们获得更多精彩 作者 | 苏星开,云和恩墨南区交付技术顾问,曾服务过通信、能源生产、金融等行业客户,擅长 SQL 审核和优化,DataGuard 容灾等。  概述这里主要介绍两种操作简易的加密脱密函数,可能也是大家都比较常用。一个是内部 translate 函数,另外一个是利用 md5 算法创建的自定义函数。介绍这两个加密方法,主要还是在对一些...

Oracle查看正在执行的存储过程

正在执行的存储过程 select owner,name from v$db_object_cache where type like '%PROCE%' and locks >0 and pins >0; 正在执行的sql select a.program, b.spid, c.sql_text,c.SQL_IDfrom v$session a...

sqlserver2008r2 版本数据库迁移到2019版本导致查询效率慢的解决方法

1、在sqlserver2008 版本的数据库引擎创建数据库后,迁移到sqlserver2019版本,存储过程查询效率变慢了。 2、主要原因:使用sqlserver2019版本的数据库软件创建,默认是不往低版本的数据库软件兼容。 3、处理版本,右击数据库-》属性-》选项-》兼容级别,选择SQL Server 2008 (100) 即可。    ...

数据库的游标概念理解

1.游标和游标的优点   在数据库中,游标是一个十分重要的概念。游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标总是与一条SQL 选择语句相关联因为游标由结果集(可以是零条、一条或由相关的选择语句检索出的多条记录)和结果集中指向特定记录的游标位置组成。当决定对结果集...

mysql事件机制——定时任务

定时任务是老生常谈了,因为我们总是需要定时修改特定的数据。 实现它的方法肯定不止一种,但我在相当长一段时间里都是用程序编码去做的,今天突然想到“为什么一定要采用调用的方式?”,用数据库自身的能力去实现不是更好么? 通过了解,mysql的事件机制可以完成定时任务,其原理是在指定的时间调用指定的存储过程。现在很简单了不是?开搞。 首先,我们需要一个存储过程,虽...