因為目前很多企業(yè)用SpringJDBC框架做數(shù)據(jù)訪問層,通過調(diào)查應(yīng)大家的要求目前我正在做將SpringJDBC融入J-Hi平臺的工作。
在以前我還真沒對各數(shù)據(jù)庫的翻頁處理做深入的分析,只是膚淺的知道SQLServer用top,Oracle用rownum,MySQL用limit通過sql語句做分頁處理,我一直認為通過對應(yīng)數(shù)據(jù)庫的這些關(guān)鍵字就可以獲取指定的數(shù)據(jù)條數(shù),而這些數(shù)據(jù)是在數(shù)據(jù)庫端就可以一次完成的。例如只取滿足條件的第11-20這10條記錄,這樣ResultSet就會只有10條結(jié)果,而事實并非如此,主要就糾結(jié)在SQLServer上。
通過做J-Hi對SpringJDBC融合的開發(fā),我才知道實際上SQLServer2000并不能滿足我們這樣現(xiàn)實的需求,而只有到了SQLServer2005這個局面才有了改觀,下面讓我們對SQLServer的分頁處理做如下分析:
SQLServer2000,由于它只提供了top關(guān)鍵字,而top的作用只是滿足條件的前多少條記錄,因此在處理翻頁時,它是將滿足條件的前多少條記錄一并取出,如每頁10條,翻到第二頁時的sql語句為
select top 20 HI_Org.* from HI_Org HI_Org
也就是說會把前20條記錄一次性丟給java形成20條記錄的結(jié)果集,而對我們來說因為是第二頁每頁10條,所就是說只要這20條記錄的后10條,前10條是沒有任何意義的垃圾數(shù)據(jù),這樣的處理機制不但效率會大大降低,而且隨著頁數(shù)的增加,比如我們要翻到第1000頁,那在結(jié)果集中就要有10000條記錄,因此也造成了資源的浪費。大家由此會推算出來,越往后翻頁,性能就越低。這種性能的低下不只是無用數(shù)據(jù)量的增加,而且也造成了對這些無用的數(shù)據(jù)處理的時間損耗。
搞笑的時,用了這么久的SQLServer卻昏然不知,等到SQLServer2005微軟才算時對此做了補充與修改,下面是SQLServer2005的SQL語句
WITH query AS (select ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __hi_row_nr__, hi_org.* from hi_org hi_org) SELECT * FROM query WHERE __hi_row_nr__ BETWEEN 11 AND 20
通過上面的語句我們可以看出SQLServer2005提供了ROW_NUMBER()方法[這個方法有點象oracle的rownum,也許微軟對于這個功能就是抄習(xí)的甲骨文也不一定,哈哈],以記錄結(jié)果集的行數(shù),不過還是點惡心,如果用之個方法還必須進行排序處理,如果沒有order by作修飾這個方法還是無效的。
通過上面的一個小功能的分析,我真是對微軟及SQLServer產(chǎn)品有些失望,如此的功能要事隔5年才完善它,而且完善的并無新意,更何況象這樣的功能就連mysql這種免費開源的產(chǎn)品都早已實現(xiàn),而SQLServer還是商業(yè)運作,真不知微軟的SQLServer在某些方面上都不如開源的產(chǎn)品它是做何感想?