sql 2012之后分页查询速度问题

80酷酷网    80kuku.com

一.sql server 2012使用offset/fetch next分页,比sql server 2005/2008中的rownumber()有显著改进。今天特地作了简单测试,现将过程分享如下:

以下是代码片段:
dbcc dropcleanbuffers
dbcc freeproccache

set statistics io on;
set statistics time on;
go

declare @page int, @size int
select @page = 3, @size = 10

;with cte as (
select top (@page * @size)
customerid,
customername,
customercity,
row_number() over(order by customername ) as seq,
count(*) over(partition by '') as total
from customers
where customercity in ('a-city','b-city')
order by customername asc
)
select * from cte
where seq between (@page - 1 ) * @size + 1 and @page * @size
order by seq;

select
*,
count(*) over(partition by '') as total
from customers
where customercity in ('a-city','b-city')
order by customerid
offset (@page -1) * @size rows
fetch next @size rows only;
go

set statistics io off;
set statistics time off;
go



结果:

二.统计信息解释

在平时优化sql的时候,最长用的就是:set statistics on,它可以用来查看我们写的查询语句到底性能如何,不过,究竟这个性能的指标是怎么样的呢?首先需要明白的,就是各项数据的意义。

以下解释来自msdn(点击查看) 

输出项 含义

table

表的名称。

scan count

执行的扫描次数。

logical reads

从数据缓存读取的页数。

physical reads

从磁盘读取的页数。

read-ahead reads

为进行查询而放入缓存的页数。

lob logical reads

从数据缓存读取的 textntextimage 或大值类型 (varchar(max)nvarchar(max)varbinary(max)) 页的数目。

lob physical reads

从磁盘读取的 textntextimage 或大值类型页的数目。

lob read-ahead reads

为进行查询而放入缓存的 textntextimage 或大值类型页的数目。

以下解释来自园子里面的一位大师,嘿嘿(点击查看原文)

扫描计数(scan count):在查询中涉及到的表被访问的次数。在我们的例子中,其中的表只被访问了1次,由于查询中不包括连接命令,这一信息并不是十分有用,但如果查询中包含有一个或多个连接,则这一信息是十分有用的。(一个循环外部的表的scan count值为1,但对于一个循环内的表而言,其值为循环的次数。可以想象得到,对于一个循环内的表而言,其scan count值越小,它所使用的资源越少,查询的性能也就越高。因此在调节一个带连接的查询的性能时,需要关注scan count的值,在进行调节时,注意观察它是增加还是减少了。)

逻辑读取(logical reads):这是set statistics io或set statistics time命令提供的最有用的 数据。我们知道,sql server在可以对任何数据进行操作前,必须首先把数据读取到其数据缓冲区中。此外,我们也知道sql server何时会从数据缓冲区中读取数据,并把数据读取到大小为8k字节的页中。那么logical reads的意义是什么呢?logical reads是指sql server为得到查询中的结果而必须从数据缓冲区读取的页数。在执行查询时,sql server不会读取比实际需求多或少的数据,因此,当在相同的数据集上执行同一个查询,得到的logical reads的数字总是相同的。(sql server执行查询时的logical reads值每一次这个数值是不会变化的。因此,在进行查询性能的调节时,这是一个可以用来衡量你的调节措施是否成功的一个很好的标准。如果 logical reads值下降,就表明查询使用的服务器资源减少,查询的性能有所提高。如果logical reads值增加,则表示调节措施降低了查询的性能。在其他条件不变的情况下,一个查询使用的逻辑读越少,其效率就越高,查询的速度就越快。)

物理读取(physical reads):物理读,在执行真正的查询操作前,sql server必须从磁盘上向数据缓冲区中读取它所需要的数据。在sql server开始执行查询前,它要作的第一件事就是检查它所需要的数据是否在数据缓冲区中,如果在,就从中读取,如果不在,sql server必须首先将它需要的数据从磁盘上读到数据缓冲区中。我们可以想象得到,sql server在执行物理读时比执行逻辑读需要更多的服务器资源。因此,在理想情况下,我们应当尽量避免物理读操作。下面的这一部分听起来让人容易感到糊涂 了。在对查询的性能进行调节时,可以忽略物理读而只专注于逻辑读。你一定会纳闷儿,刚才不是还说物理读比逻辑读需要更多的服务器资源吗?情况确实是这样, sql server在执行查询时所需要的物理读次数不可能通过性能调节而减少的。减少物理读的次数是dba的一项重要工作,但它涉及到整个服务器性能的调节,而 不仅仅是查询性能的调节。在进行查询性能调节时,我们不能控制数据缓冲区的大小或服务器的忙碌程度以及完成查询所需要的数据是在数据缓冲区中还是在磁盘 上,唯一我们能够控制的数据是得到查询结果所需要执行的逻辑读的次数。因此,在查询性能的调节中,我们可以心安理得地不理会set statistics io命令提供的physical read的值。(减少物理读次数、加快sql server运行速度的一种方式是确保服务器的物理内存足够多。)

预计(read-ahead reads):与physical reads一样,这个值在查询性能调节中也没有什么用。read-ahead reads表示sql server在执行预读机制时读取的物理页。为了优化其性能,sql server在认为它需要数据之前预先读取一部分数据,根据sql server对数据需求预测的准确程度,预读的数据页可能有用,也可能没用。

分享到
  • 微信分享
  • 新浪微博
  • QQ好友
  • QQ空间
点击: