C#调用Oracle存储过程或函数返回结果集效率测试
作者:肖凤斌 E-mail:binsweet@gmail.com
在SqlServer中可以较容易的使用存储过程返回结果集,但在Oracle中却比较困难,因为Oracle中不支持过程返回结果集,只能用动态游标来替代实现。
实现方法如下:
环境:Oracle 9.2.0.1 + asp.net(C#)
oracle中创建函数:
CREATE OR REPLACE FUNCTION fun_test RETURN SYS_REFCURSOR IS
RESULT SYS_REFCURSOR;
BEGIN
OPEN RESULT FOR 'SELECT * FROM t_test where rownum<1001';
RETURN(RESULT);
END fun_test;
C#测试语句:
long t1,t0 = System.DateTime.Now.Ticks;
DataSet ds = new DataSet();
try
{
this.DBConnection();
this.cmd.CommandText = "fun_test";
this.cmd.CommandType = CommandType.StoredProcedure;
this.cmd.Parameters.Add("ReturnValue", OracleType.Cursor);
this.cmd.Parameters["ReturnValue"].Direction = ParameterDirection.ReturnValue;
this.da.SelectCommand = this.cmd;
this.da.Fill(ds, "RESULT");
}
catch (Exception e)
{
throw (e);
}
t1 = DateTime.Now.Ticks - t0;
注意调用的时候函数返回值类型为OracleType.Cursor。
这样就可以在存储过程或函数中返回结果集了,但是由于使用了动态游标,其效率很让人不放心,因此做了如下对照试验:
long t1, t0 = System.DateTime.Now.Ticks;
DataSet temp = new DataSet();
try
{
this.cmd.CommandText = "SELECT * FROM t_test where rownum<1001";
this.da.SelectCommand = this.cmd;
this.da.Fill(temp,TableName);
} //结束try
catch (Exception e)
{
throw(e);
}
t1 = DateTime.Now.Ticks - t0;
当取10000条记录时,耗时Ticks如下:
第一次 | 第二次 | 第三次 | 刷新页面 | 刷新页面 | 刷新页面 | 刷新页面 | 平均值 | |
利用函数 | 13906250 | 14687500 | 14218750 | 14531250 | 13906250 | 13125000 | 12812500 | 13883928.57 |
普通方式 | 625000 | 625000 | 625000 | 156250 | 156250 | 156250 | 156250 | 357142.86 |
结论:可以看到,取1万条记录时,其效率存在数量级的差异,普通方式比用函数返回结果集的效率要高两个数量级,因此想使用oracle存储过程或函数返回结果集时要慎重考虑效率问题。