今天的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
鳥生魚湯 閱讀(2063)
評論(0) 編輯 收藏