本文旨在介紹一種對(duì)數(shù)據(jù)庫(kù)中的大數(shù)據(jù)量表格進(jìn)行分頁(yè)查詢的實(shí)現(xiàn)方法,該方法對(duì)應(yīng)用服務(wù)器、數(shù)據(jù)庫(kù)服務(wù)器、查詢客戶端的cpu和內(nèi)存占用都較低,查詢速度較快,是一個(gè)較為理想的分頁(yè)查詢實(shí)現(xiàn)方案。
1.問(wèn)題的提出
在軟件開(kāi)發(fā)中,大數(shù)據(jù)量的查詢是一個(gè)常見(jiàn)的問(wèn)題,經(jīng)常會(huì)遇到對(duì)大量數(shù)據(jù)進(jìn)行查詢的場(chǎng)景。常見(jiàn)的對(duì)大數(shù)據(jù)量查詢的解決方案有以下兩種:一、將全部數(shù)據(jù)先查詢到內(nèi)存中,然后在內(nèi)存中進(jìn)行分頁(yè),這種方式對(duì)內(nèi)存占用較大,必須限制一次查詢的數(shù)據(jù)量。二、采用存儲(chǔ)過(guò)程在數(shù)據(jù)庫(kù)中進(jìn)行分頁(yè),這種方式對(duì)數(shù)據(jù)庫(kù)的依賴較大,不同的數(shù)據(jù)庫(kù)實(shí)現(xiàn)機(jī)制不通,并且查詢效率不夠理想。以上兩種方式對(duì)用戶來(lái)說(shuō)都不夠友好。
2.解決思路
通過(guò)在待查詢的數(shù)據(jù)庫(kù)表上增加一個(gè)用于查詢的自增長(zhǎng)字段,然后采用該字段進(jìn)行分頁(yè)查詢,可以很好地解決這個(gè)問(wèn)題。下面舉例說(shuō)明這種分頁(yè)查詢方案。
一、在待查詢的表格上增加一個(gè)long型的自增長(zhǎng)列,取名為“queryId”,mssql、sybase直接支持自增長(zhǎng)字段,oracle可以用sequence和trigger來(lái)實(shí)現(xiàn)。然后在該列上加上一個(gè)索引。添加queryId列的語(yǔ)句如下:
Mssql: [QUERYID] [bigint] IDENTITY (1, 1)
Sybase: QUERYID numeric(19) identity
www.yueluo.net Oracle:
CREATE SEQUENCE queryId_S
INCREMENT BY 1
START WITH 1
MAXVALUE 999999999999999 MINVALUE 1
CYCLE
CACHE 20
ORDER;
CREATE OR REPLACE TRIGGER queryId_T BEFORE INSERT
ON "test_table"
FOR EACH ROW
BEGIN
select queryId_S.nextval into :new.queryId from dual;
END;
二、在查詢第一頁(yè)時(shí),先按照大小順序的倒序查出所有的queryId,語(yǔ)句如下:select queryId from test_table where + 查詢條件 +order by queryId desc 。因?yàn)橹皇遣樵僸ueryId字段,即使表格中的數(shù)據(jù)量很大,該查詢也會(huì)很快得到結(jié)果。然后將得到的queryId保存在應(yīng)用服務(wù)器的一個(gè)數(shù)組中。 字串9
三、用戶在客戶端進(jìn)行翻頁(yè)操作時(shí),客戶端將待查詢的頁(yè)號(hào)作為參數(shù)傳遞給應(yīng)用服務(wù)器,服務(wù)器通過(guò)頁(yè)號(hào)和queyId數(shù)組算出待查詢的queyId最大和最小值,然后進(jìn)行查詢。
算出queyId最大和最小值的算法如下,其中page為待查詢的頁(yè)號(hào),pageSize為每頁(yè)的大小,queryIds為第二步生成的queryId數(shù)組:
int startRow = (page - 1) * pageSize;
int endRow = page * pageSize - 1;
if (endRow >=queryIds.length)
{
endRow = this.queryIds.length - 1;
}
long startId =queryIds[startRow];
long endId =queryIds[endRow];
查詢語(yǔ)句如下:
String sql = "select * from test_table" + 查詢條件 + "(queryId <= " + startId + " and queryId >= " + endId + ")";
字串7