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