今天的hibernate调用的存储过程,分页的时候执行速度太慢,要1分钟。
折腾了半天终于解决了。
最开始以为存储过程返回了所有的结果,通过实际要求简化为返回75行记录。发现效果不明显
接着是为了好分页,需要返回一个查询的对象序列,存储过程先返回一个ID,然后把ID做成一个序列,在通过hibernate的配置的执行返回的对象集合,并且这样分页方便。hql语句是:from Bed as b WHERE b.id IN (:list) order by charindex(','+rtrim(id)+',' , '''' + :list2 + '''')
以为二次搜索的原因。然后换别的分页方式,在网上找了大概有三种存储过程分页方式。
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
ALTER proc sp_LaborFiles_GetList
@PageNo int=1,
@PageCount int output
as
declare @PageSize int
declare @RowCount int
DECLARE @p1 INT
DECLARE @sql nvarchar(1000)
SET @PageSize = 20
set @sql = N'select ID,FileName,CreateDate from T_Files Where Deleted = 0 and ( Type=''labor''or Type=''公用'') ORDER BY ID DESC'
EXEC sp_cursoropen @p1 OUTPUT,@Sql,@scrollopt=1,@ccopt=1,@rowcount=@RowCount output
if (@RowCount%@PageSize = 0)
SET @PageCount = @RowCount/@PageSize
ELSE
SET @PageCount = @RowCount/@PageSize + 1
SET @PageNo = (@PageNo - 1) * @PageSize + 1
EXEC SP_CURSORFETCH @P1,16,@PageNo,@PageSize
EXEC SP_CURSORCLOSE @P1
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
这个方式执行效率也不好,还返回了两个结果集。
Connection con = session.connection();
CallableStatement sm = con.prepareCall("{call up_Bed_Assign(?,?,?,?,?,?,?,?,?,?)}");
sm.setString(1, c.getDepartment());
sm.setString(2, c.getDivision());
.....
ResultSet set = sm.getResultSet();
当遍历set.next()时,返回false,怎么取得第二个结果集尚未得知。这个执行速度也慢。
通过int id = set.getInt("ID"); 这样的函数取字段然后重建对象返回对象的集合。
在查了一下也许是采用了callableStatement类的方式,其实前者效率貌似更高, 于是采用
Session session = CommonDAO.getSession();
Query q = session.getNamedQuery("selectB");
q.setString(0, c.getDepartment());
q.setString(1, c.getDivision());
q.setString(2, c.getBuildingNo());
.....
List lst = q.list();
这样的方式,需要在..hbm.xml里面配置
<sql-query name="selectB">
<![CDATA[ {call up_Bed_Assign(?,?,?,?,?,?,?,?,?,?)} ]]>
</sql-query>
这样取出来的是对象集合
for(Object obj : lst){
Object[] objs = (Object[]) obj;
Bed b = new Bed();
b.setId(Integer.parseInt(objs[0].toString()));
还得判断空值的情况,很麻烦。
最后从事件监听器得到的语句是
SELECT @@MAX_PRECISION
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SET IMPLICIT_TRANSACTIONS OFF
SET QUOTED_IDENTIFIER ON
SET TEXTSIZE 2147483647
SET IMPLICIT_TRANSACTIONS ON
declare @P1 int
exec sp_prepare @P1 output, N'@P0 nvarchar(4000),@P1 nvarchar(4000),@P2 nvarchar(4000),@P3 nvarchar(4000),@P4 bit,@P5 int,@P6 int,@P7 int,@P8 int,@P9 int', N'EXECUTE up_Bed_Assign @P0 , @P1 , @P2 , @P3 , @P4 , @P5 , @P6 , @P7 , @P8 , @P9 '
select @P1
exec sp_execute @P1, N'', N'', N'', N'', 0, 1, 0, 0, 1, 5
整个存储过程影响了5000+5000+5000+20000多行数据,寒!赶紧优化存储过程,只需要搜索结果的一部分值就可以了。
再进行修改一下。总结一下遇到如下问题
一是存储过程分页
二是存储过程返回结果集后的处理,多个结果集的处理
三是hibernate里面调用存储过程的方式和配置
四是存储过程的书写,游标使用
posted on 2008-06-17 18:16
鸟生鱼汤 阅读(2061)
评论(0) 编辑 收藏