首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

关于逻辑读,该怎么处理

2012-02-19 
关于逻辑读我用的是SQL2005自带的AdventureWorks数据库,在执行如下语句时:SQL codeselect * from Sales.Sa

关于逻辑读
我用的是SQL2005自带的AdventureWorks数据库,在执行如下语句时:

SQL code
select * from Sales.SalesOrderHeader where customerid='676' 

查看执行计划:
SQL code
Table 'SalesOrderHeader'. Scan count 1, logical reads 38, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

按照我的理解,其中逻辑读38应该是从数据缓冲区读区的页数,可上述SQL语句只返回12行记录,怎么会有38个数据页呢,请问这个逻辑读的数字到底代表什么呢,麻烦给我这个新手讲解下SQL执行计划一些数字的含义(比如物理读,预读等)

[解决办法]
看看这个;
I/O 构架
数据库的主要作用是存储和检索数据,因此执行大量磁盘读写操作是数据库引擎的固有特性之一。磁盘 I/O 操作消耗很多资源,且需相对较长的时间才能完成。在关系数据库软件中,多数逻辑都涉及高效地建立 I/O 使用模式。

Microsoft® SQL Server? 2000 将很多虚拟内存分配给高速缓冲存储器,并使用此高速缓存减少物理 I/O。每个 SQL Server 2000 实例都有自己的高速缓冲存储器。数据从数据库磁盘文件读入高速缓冲存储器。不必再次物理读取数据即可满足多次逻辑读取数据。数据一直保留在高速缓存内,直到已有一段时间不被引用且数据库需要缓存区读入更多数据。数据只有在被修改后才重新写入磁盘。在物理写将新数据传输回磁盘之前,数据可由逻辑写多次修改。

在 SQL Server 2000 数据库内的数据存储在 8 KB 页内。每组的八个邻接页是一个 64 KB 扩展盘区。高速缓冲存储器也被划分为 8 KB 页。

SQL Server 实例的 I/O 被划分为逻辑和物理 I/O。数据库服务器每次从高速缓冲存储器请求页时,即发生逻辑读取。如果页当前不在缓存区高速缓存内,则执行物理读取将页读入高速缓冲存储器。如果页当前在高速缓存内,则不产生物理读取;高速缓冲存储器只是使用已在内存内的页。当内存中页内的数据被修改时,发生逻辑写。当将页写入磁盘时,发生物理写。在将页物理写入磁盘之前,它有可能在内存内停留足够长的时间以至发生多次逻辑写。

SQL Server 实例的基本性能优化任务之一包括调整 SQL Server 内存的大小。目的是使高速缓冲存储器足够大以使逻辑读取与物理读取的比率达到最大,但又不至大到使过多的内存交换开始对页文件产生物理 I/O。SQL Server 2000 实例在默认配置设置下自动完成这一任务。

通过在虚拟内存内保持相对较大的高速缓冲存储器,SQL Server 实例可以显著减少所需的物理磁盘读取数。一个经常引用的页被读入高速缓冲存储器后很可能会继续留在那里,因此完全不用再进一步读取。

SQL Server 2000 使用 Microsoft Windows NT® 和 Windows® 2000 的下面两个功能来提高其磁盘的 I/O 性能: 

散播-聚集 I/O 
在 Windows NT 4.0版 Service Pack 2 中引入散播-聚集 I/O 之前,Windows NT 上所有用于磁盘读写的数据必须在邻接的内存区内。如果某个读取以 64 KB 为单位传送数据,则读取请求必须指定邻接 64 KB 内存区域的地址。散播-聚集 I/O 允许读取或写入操作将数据传入或传出内存的非邻接区域。Windows 2000 也支持散播-聚集 I/O。

如果 SQL Server 2000 实例在 64 KB 扩展盘区中读取,则不须分配单个 64 KB 区并将各个页复制到高速缓冲存储器页内。它可以找到八个缓冲区页,然后执行一个散播-聚集 I/O 以指定这八个缓冲区页的地址。Windows NT 或 Windows 2000 直接在缓冲区页内放入八个页,使 SQL Server 实例不需要执行单独的内存复制。

异步 I/O 
在异步 I/O 中,应用程序从 Windows NT 或 Windows 2000 中请求读取或写入操作。Windows NT 或 Windows 2000 立即将控制返回给应用程序。应用程序然后可以执行其它的工作,过一会儿执行测试以查看读写操作是否已完成。相反,在同步 I/O 中,操作系统直到读和写完成才将控制返回给应用程序。使用异步 I/O 使 SQL Server 实例得以在个别线程执行批处理时使它们所完成的工作最多。

SQL Server 支持对每个文件执行多个并发异步 I/O 操作。SQL Server 2000 动态确定一个实例能为任何文件发出的最大 I/O 操作数。


[解决办法]
scan count


执行的扫描次数。

logical reads


从数据缓存读取的页数。

physical reads


从磁盘读取的页数。

read-ahead reads


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

lob logical reads


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

lob physical reads


从磁盘读取的 text、ntext、image 或大值类型页的数目。

lob read-ahead reads


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

參照說明

http://technet.microsoft.com/zh-cn/library/ms184361(SQL.90).aspx
[解决办法]
引用楼主 realconnection 的帖子:
我用的是SQL2005自带的AdventureWorks数据库,在执行如下语句时:

SQL codeselect * from Sales.SalesOrderHeader where customerid='676'


查看执行计划:

SQL codeTable 'SalesOrderHeader'. Scan count 1, logical reads 38, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.



按照我的理解,其中逻辑读38应该是从数据缓冲区读区的页数,可上述SQL语…

[解决办法]
如果你执行:
SQL code
select * from Sales.SalesOrderHeader where 排序列='xxx'
------解决方案--------------------


了解查詢性能,樓主可參照邏輯與實體運算子參考
http://technet.microsoft.com/zh-tw/library/ms191158(SQL.90).aspx
[解决办法]

引用楼主 realconnection 的帖子:
我用的是SQL2005自带的AdventureWorks数据库,在执行如下语句时:
SQL codeselect*fromSales.SalesOrderHeaderwherecustomerid='676'
查看执行计划:
SQL codeTable'SalesOrderHeader'. Scancount1, logical reads38, physical reads0,read-ahead reads0, lob logical reads0, lob physical reads0, lobread-ahead reads0.
按照我的理解,其中逻辑读38应该是从数据缓冲区读区的页数,可上述SQL语句只返回12行记录,怎么会有38个数据…

[解决办法]
引用楼主 realconnection 的帖子:
我用的是SQL2005自带的AdventureWorks数据库,在执行如下语句时:
SQL codeselect*fromSales.SalesOrderHeaderwherecustomerid='676'
查看执行计划:
SQL codeTable'SalesOrderHeader'. Scancount1, logical reads38, physical reads0,read-ahead reads0, lob logical reads0, lob physical reads0, lobread-ahead reads0.
按照我的理解,其中逻辑读38应该是从数据缓冲区读区的页数,可上述SQL语句只返回12行记录,怎么会有38个数据…

[解决办法]
我通过sys.dm_db_index_physical_stats函数获取该表索引的数据页层次结构
SQL code
SELECT * FROM sys.dm_db_index_physical_stats(DB_ID(N'AdventureWorks'), OBJECT_ID(N'Sales.SalesOrderHeader'), NULL, NULL , 'DETAILED');
[解决办法]
引用楼主 realconnection 的帖子:
我用的是SQL2005自带的AdventureWorks数据库,在执行如下语句时:
SQL codeselect*fromSales.SalesOrderHeaderwherecustomerid='676'
查看执行计划:
SQL codeTable'SalesOrderHeader'. Scancount1, logical reads38, physical reads0,read-ahead reads0, lob logical reads0, lob physical reads0, lobread-ahead reads0.
按照我的理解,其中逻辑读38应该是从数据缓冲区读区的页数,可上述SQL语句只返回12行记录,怎么会有38个数据…

热点排行