我们的生活越来越精彩
学无止境,恒心,毅力,坚持
posts - 20,  comments - 6,  trackbacks - 0
    今天的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 鸟生鱼汤 阅读(2053) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航:
 

<2008年6月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

常用链接

留言簿(2)

随笔档案

文章档案

喜欢的技术博客

喜欢的有意思有味道的博客 放松并鼓励自己

搜索

  •  

最新评论

阅读排行榜

评论排行榜