今天在開(kāi)發(fā)的時(shí)候用了oracle的分頁(yè),語(yǔ)句如下(ibatis)
SELECT *
FROM (SELECT t1.*,rownum as linenum
FROM (SELECT
A.MEMBERID memberID,
A.LOGNAME logName,
A.STATUS status,
A.UPDATETIME updateTime,
A.OPERATORNAME operatorName
FROM BD_BAOYANG_LIST A
WHERE
<![CDATA[
A.TYPE='BUY'
]]>
<dynamic>
<isEqual property="status" compareValue="1" prepend="and">
A.STATUS=1
</isEqual>
<isEqual property="status" compareValue="-1" prepend="and">
<![CDATA[
A.STATUS<>1
]]>
</isEqual>
<isNotEmpty property="memberID" prepend="and">
A.MEMBERID = #memberID#
</isNotEmpty>
<isNotEmpty property="logName" prepend="and">
A.LOGNAME = #logName#
</isNotEmpty>
<isNotEmpty property="startTime" prepend="and">
<![CDATA[
A.UPDATETIME >= cast(#startTime# as DATE)
]]>
</isNotEmpty>
<isNotEmpty property="endTime" prepend="and">
<![CDATA[
A.UPDATETIME < cast(#endTime# as DATE)+1
]]>
</isNotEmpty>
</dynamic>
<![CDATA[
ORDER BY A.UPDATETIME DESC) t1
WHERE ROWNUM <= #endRow#) t2
WHERE linenum >= #startRow#
]]>
在運(yùn)行后發(fā)現(xiàn)查詢(xún)出來(lái)的結(jié)果總條數(shù)和數(shù)據(jù)庫(kù)里的記錄數(shù)量是一致的,但是出現(xiàn)了數(shù)據(jù)重復(fù)現(xiàn)象,也就是說(shuō)有些數(shù)據(jù)被重復(fù)的記錄替換了。
一開(kāi)始以為是Java程序邏輯問(wèn)題,經(jīng)過(guò)認(rèn)真的排查,排除了程序的問(wèn)題。
仔細(xì)看了一下數(shù)據(jù)庫(kù)里的數(shù)據(jù),發(fā)現(xiàn)UPDATETIME這一列的數(shù)據(jù)格式是yyyy-MM-dd沒(méi)有小時(shí)-分-秒的。這樣該列的數(shù)據(jù)就出現(xiàn)了重復(fù)現(xiàn)象,這時(shí)我產(chǎn)生了疑問(wèn):難道oracle在對(duì)數(shù)據(jù)進(jìn)行排序的時(shí)候?qū)χ貜?fù)的排序條件是不能保證順序的不變性?
帶著這個(gè)問(wèn)題我查詢(xún)了oarcle的相關(guān)資料。
經(jīng)過(guò)查詢(xún)資料發(fā)現(xiàn),oracle在對(duì)小量數(shù)據(jù)查詢(xún)的時(shí)候會(huì)將數(shù)據(jù)放到緩存內(nèi)進(jìn)行排序,當(dāng)數(shù)據(jù)量達(dá)到一定程度時(shí)會(huì)將數(shù)據(jù)在磁盤(pán)排序,而磁盤(pán)排序時(shí)當(dāng)遇到排序條件相同的情況下,會(huì)根據(jù)該條記錄的更新時(shí)間進(jìn)行排序(我想可能是ROWID

),但是如果放到內(nèi)存排序的話如果不指定排序條件就不會(huì)走更新時(shí)間,因此我在上面的程序ORDER BY A.UPDATETIME DESC 修改成ORDER BY A.UPDATETIME DESC,A.ROWID DESC這樣就解決了問(wèn)題,但是這樣解決的方式十分的不優(yōu)雅,第一:這樣UPDATETIME上建立的索引就不再起作用,第二:當(dāng)該表數(shù)據(jù)量很大的時(shí)候,就會(huì)導(dǎo)致查詢(xún)非常耗時(shí),但是業(yè)務(wù)要求又必須按照UPDATETIME來(lái)進(jìn)行排序,因此建議如果表的數(shù)據(jù)量很大就應(yīng)該將該時(shí)間字段 提供 小時(shí)/分鐘/秒鐘
OVER!!!!!!!!!!!!