sqlserver中使用row_number进行分页,效率很高!速度很快!
????????????????? 最近,童鞋要做一个分页,数据量很大,几十万条数据,更坑爹的是,还是要经过表连接进行查询,速度慢得像乌龟!! ?????????????????? ???????????????? 怎么进行优化,可以让逻辑更清晰,效率更高呢?我试探的过程大概分为以下几个步骤: ????????????? 1.首先因为要进行多张表连接,所以在数据库中先做了一个视图,把表连接起来。(但是这样查询速度和直接在sql语句中写表连接差不多,但是如果把表连接写在视图中,程序中的sql语句将变得简洁,思路更清晰) 建立视图的sql语句如下:视图名为searchJCR SELECT dbo.JCR_Table.JournalID,dbo.JCR_Table.JournalFullTitle,dbo.JCR_Table.JournalISOTitle,dbo.JCR_Table.JournalJCRTitle,dbo.JCR_Table.JournalISSN,dbo.JCR_Table.JournalLanguage,dbo.JCR_Table.JournalUpdateYear,dbo.SubjectCategories.TotalJouranls,dbo.SubjectCategories.JournalRank,dbo.SubjectCategories.JournalQuartile,dbo.JCRCategory_Table.CategoriesEName,dbo.JCRCategory_Table.CategoriesCName,dbo.JCRIF_Table.YearNum,dbo.JCRIF_Table.IFScore,dbo.JCRCategory_Table.CategoriesID FROM dbo.JCR_Table INNER JOIN dbo.JCRIF_Table ON dbo.JCR_Table.JournalID = dbo.JCRIF_Table.JournalID INNER JOIN dbo.SubjectCategories ON dbo.JCR_Table.JournalID = dbo.SubjectCategories.JournalID AND dbo.SubjectCategories.YearNum = dbo.JCRIF_Table.YearNum INNER JOIN dbo.JCRCategory_Table ON dbo.SubjectCategories.CategoriesID = dbo.JCRCategory_Table.CategoriesID????????????????????????? ? 2.然后再程序中使用传统方法进行分页。 这时候出现了一个问题,使用的视图查询出来的结果又很多JournalID重复的记录,这样使用JournalID进行分页就不可行了。所以需要做的就是为每一条查询记录指定唯一一个标识,在oracle中有伪列rowid,可以用于区分每一条记录,在sql server2005之前,没有办法区分,但是在sql2005之后,提供了一个ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN)函数用于实现类似于伪列的效果。 ??????????????????????? 3.然后在程序中使用row_number()over()进行分页。语句如下 select top 20 * from (select row_number()over(order by YearNum DESC,JournalID ASC) as rowid,sJCR.* from searchJCR as sJCR)where rowid not in(select top 20*queryPage rowid from (select row_number()over(order by YearNum DESC,sJCR1.* from searchJCR as sJCR1) where 1=1 and ...) and 1=1 and... order by YearNumDESC,JournalID ASC
查询速度很慢。后来做了优化(CTE,关于CTE的介绍将读者参阅《SQL Server2005杂谈(1):使用公用表表达式(CTE)简化嵌套SQL》),优化后的代码如下: with t_rowtable?? row_number函数的用途是非常广泛,这个函数的功能是为查询出来的每一行记录生成一个序号,生成的机制是,按over(排序条件)中的排序条件对每条记录顺序生成一个rowid,然后将记录按select的order by顺序显示出来。其中“where row_number>100 row_number列是由row_number函数生成的序号列。在使用row_number函数是要使用over子句选择对某一列进行排序,然后才能生成序号。 ??? 实际上,row_number函数生成序号的基本原理是先使用over子句中的排序语句对记录进行排序,然后按着这个顺序生成序号。over子句中的order by子句与SQL语句中的order by子句没有任何关系,这两处的order by 可以完全不同,如下面的SQL语句所示: ? select ?row_number()? over ( order ?by?field2?desc)?as?row_number,*?from?t_table?order?by?field1?desc? ??? 上面的SQL语句的查询结果如图所示。 另外要注意的是,如果将row_number函数用于分页处理,over子句中的order by 与排序记录的order by 应相同,否则生成的序号可能不是有续的。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |