對於一萬條數據量使用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

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM