WEB开发网
开发学院数据库MSSQL Server SQL Server 2005 Beta 2 Transact-SQL 增强功能 1... 阅读

SQL Server 2005 Beta 2 Transact-SQL 增强功能 1

 2007-11-11 04:46:31 来源:WEB开发网   
核心提示: 我在我的膝上型电脑(Compaq Presario X1020U,CPU:Centrino 1.4 GH,SQL Server 2005 Beta 2 Transact-SQL 增强功能 1(2),RAM:1GB,本地 HD)上运行该测试,以标识应该为其独立计算排序值的行组,例如,sql server(WINDOWS

我在我的膝上型电脑(Compaq Presario X1020U,CPU:Centrino 1.4 GH,RAM:1GB,本地 HD)上运行该测试。sql server(WINDOWS平台上强大的数据库平台) 2005 查询只需 1 秒即可完成,而 sql server(WINDOWS平台上强大的数据库平台) 2000 查询大约需要 12 分钟才能完成。

行号的一个典型应用是通过查询结果分页。给定页大小(以行数为单位)和页号,需要返回属于给定页的行。例如,假设您希望按照“score DESC, speaker”顺序从 SpeakerStats 表中返回第二页的行,并且假定页大小为三行。下面的查询首先按照指定的排序计算派生表 D 中的行数,然后只筛选行号为 4 到 6 的行(它们属于第二页):

SELECT *FROM (SELECT ROW_NUMBER() OVER(ORDER BY score DESC, speaker) AS rownum,speaker, track, scoreFROM SpeakerStats) AS DWHERE rownum BETWEEN 4 AND 6ORDER BY score DESC, speaker

以下为结果集:

rownum speaker    track      score------ ---------- ---------- -----------4      Kathy      Sys        85      Michele    Sys        86      Mike       DB         8

用更一般的术语表达就是,给定 @pagenum 变量中的页号和 @pagesize 变量中的页大小,以下查询返回属于预期页的行:

DECLARE @pagenum AS INT, @pagesize AS INTSET @pagenum = 2SET @pagesize = 3SELECT *FROM (SELECT ROW_NUMBER() OVER(ORDER BY score DESC, speaker) AS rownum,speaker, track, scoreFROM SpeakerStats) AS DWHERE rownum BETWEEN (@pagenum-1)*@pagesize+1 AND @pagenum*@pagesizeORDER BY score DESC, speaker

上述方法对于您只对行的一个特定页感兴趣的特定请求而言已经足够了。但是,当用户发出多个请求时,该方法就不能满足需要了,因为该查询的每个调用都需要您对表进行完整扫描,以便计算行号。当用户可能反复请求不同的页时,为了更有效地进行分页,请首先用所有基础表行(包括计算得到的行号)填充一个临时表,并且对包含这些行号的列进行索引:

SELECT ROW_NUMBER() OVER(ORDER BY score DESC, speaker) AS rownum, *INTO #SpeakerStatsRNFROM SpeakerStatsCREATE UNIQUE CLUSTERED INDEX idx_uc_rownum ON #SpeakerStatsRN(rownum)

然后,对于所请求的每个页,发出以下查询:

SELECT rownum, speaker, track, scoreFROM #SpeakerStatsRNWHERE rownum BETWEEN (@pagenum-1)*@pagesize+1 AND @pagenum*@pagesizeORDER BY score DESC, speaker

只有属于预期页的行才会被扫描。

分段

可以在行组内部独立地计算排序值,而不是为作为一个组的所有表行计算排序值。为此,请使用 PARTITION BY 子句,并且指定一个表达式列表,以标识应该为其独立计算排序值的行组。例如,以下查询按照“score DESC, speaker”顺序单独分配每个 track 内部的行号:

SELECT track,ROW_NUMBER() OVER(PARTITION BY trackORDER BY score DESC, speaker) AS pos,speaker, scoreFROM SpeakerStatsORDER BY track, score DESC, speaker

以下为结果集:

track      pos speaker    score---------- --- ---------- -----------DB         1   Suzanne    9DB         2   Mike       8DB         3   Kevin      7Dev        1   Jessica    9Dev        2   Ron        9Dev        3   Joe        6Dev        4   Robert     6Sys        1   Kathy      8Sys        2   Michele    8Sys        3   Brian      7Sys        4   Dan        3

在 PARTITION BY 子句中指定 track 列会使得为具有相同 track 的每个行组单独计算行号。

上一页  1 2 3 4 5 6 7  下一页

Tags:SQL Server

编辑录入:coldstar [复制链接] [打 印]
赞助商链接