天天看点

mysql逻辑读高影响_逻辑读、物理读、预读的理解

通过以下语句清楚数据缓存并开启IO统计:

DBCC DROPCLEANBUFFERS; --清除缓存

SET STATISTICS IO ON; --开启IO统计

SELECT * FROM FoodCorp;

示例:

mysql逻辑读高影响_逻辑读、物理读、预读的理解

一、相关定义

SQL SERVER 数据库引擎当遇到一个查询语句时,SQL SERVER数据库引擎会分别生成执行计划(占用CPU和内存资源),同时存储引擎读取 IAM 以生成必须要读取的磁盘地址排序列表。这使 SQL Server 得以将其 I/O 优化为大型有序读取,根据它们在磁盘上的位置按顺序完成。磁盘中取得需要取的数据(占用I/O资源,这就是预读),注意,两个步骤是并行的,SQL SERVER通过这种方式可以让计算和 I/O 重叠进行,从而充分利用 CPU 和磁盘,从而提高性能。

扫描计数:查询数据时对涉及到的表被访问次数或涉及到的索引的扫描次数。对于查询中不包括连接命令时,这一信息并不是十分有用,但如果查询中包含有一个或多个连接,则十分有用。

一个循环外部的表的扫描计数值为1,但对于一个循环内的表而言,其值为循环的次数。可以想象得到,对于一个循环内的表而言,其扫描计数值越小,它所使用的资源越少,查询的性能也就越高。因此在调节一个带连接的查询的性能时,需要关注扫描计数的值,在进行调节时,注意观察它是增加还是减少了。

逻辑读: 这是SET STATISTICS IO或SET STATISTICS TIME命令提供的最有用的数据。SQL Server在对任何数据进行操作前,必须首先从磁盘中读取数据所在的数据页或索引页,并把数据页或索引页存到数据缓冲区高速缓存中。

逻辑读是指SQL Server为得到查询中的结果而必须从数据缓冲区高速缓存读取的页数。在执行查询时,SQL Server不会读取比实际需求多或少的数据, 因此,当在相同的数据集上执行同一个查询,得到的逻辑读的数字总是相同的。

在每次执行同一查询时,这个数值是不会变化的。因此,在进行查询性能的调节时,这是一个可以用来衡量你的调节措施是否成功的一个很好的标准。

在对查询的性能进行调节时,如果逻辑读值下降,就表明查询使用的服务器资源减少,查询的性能有所提高。如果逻辑读值增加,则表示调节措施降低了查询的性能。在其他条件不变的情况下,一个查询使用的逻辑读越少,其效率就越高,查询的速度就越快。

物理读:指的是,在执行真正的查询操作前,SQL Server必须从磁盘上向数据缓冲区高速缓存中读取它所需要的数据。在SQL Server开始执行查询前,它要作的第一件事就是检查它所需要的数据是否在数据缓冲区高速缓存中,如果在,就从中读取,如果不在,SQL Server必须首先将它需要的数据从磁盘上读到数据缓冲区高速缓存中。

SQL Server在执行物理读时比执行逻辑读需要更多的服务器资源。因此,在理想情况下,我们应当尽量避免物理读操作。

在对查询的性能进行调节时,可以忽略物理读而只专注于逻辑读。SQL Server在执行查询时所需要的物理读次数不可能通过性能调节而减少的。减少物理读的次数是DBA的一项重要工作,但它涉及到整个服务器性能的调节,而不仅仅是查询性能的调节。在进行查询性能调节时,我们不能控制数据缓冲区高速缓存的大小或服务器的忙碌程度以及完成查询所需要的数据是在数据缓冲区中还是在磁盘上,唯一我们能够控制的数据是得到查询结果所需要执行的逻辑读的次数。

减少物理读次数、加快SQL Server运行速度的一种方式是确保服务器的物理内存足够多。

预读:预读表示SQL Server在执行预读机制时从磁盘上读取的数据页或索引页。为了优化其性能,SQL Server数据引擎首先预测执行查询执行计划所需的数据和索引页,然后在查询实际使用这些页之前将它们读入缓冲区高速缓存。根据SQL Server对数据需求预测的准确程度,预读的数据页可能有用,也可能没用。与物理读一样,这个值在查询性能调节中也没有什么用处。

注意:一个缓冲区就是一个 8KB 大小的内存页

二、分析

SQL SERVER数据存储的方式:存储的最小单位为页(Page).每一页大小为8k,SQL SERVER对于页的读取是原子性,要么读完一页,要么完全不读,不会有中间状态。而页之间的数据组织结构为B树。所以SQL SERVER对于逻辑读,预读,和物理读的单位是页。

SQL SERVER一页的总大小为:8K

页存储的数据为:8192字节-96字节(页头)-36字节(行偏移)=8060字节

所以每一页用于存储的实际大小为8060字节。

通过表属性→存储,看到这个表的数据空间为5.336M:

mysql逻辑读高影响_逻辑读、物理读、预读的理解

可以通过公式大概推算出占用了多少页:

5.336*1024*1024/8060(每页的数据容量)≈ 694 - 表中非数据占用的空间 ≈687(逻辑读取数)

SQL SERVER查询执行的步骤如果从微观来看,那将会非常多。这里为了讲述逻辑读等概念,从比较高的抽象层次来看:

mysql逻辑读高影响_逻辑读、物理读、预读的理解

当遇到一个查询语句时,SQL SERVER会走第一步,分别为生成执行计划(占用CPU和内存资源),同步的用估计的数据去磁盘中取得需要取的数据(占用IO资源,这就是预读),注意,两个第一步是并行的,SQL SERVER通过这种方式来提高查询性能。

然后查询计划生成好了以后去缓存读取数据.当发现缓存缺少所需要的数据后让缓存再次去读硬盘(物理读)。

最后从缓存中取出所有数据(逻辑读)。

示例中的“ 预读703次 ”即为估计的页数,可以通过这个DMV看到该数据:

SELECTpage_countFROM sys.dm_db_index_physical_stats(DB_ID('foodtrace_fwq'),OBJECT_ID('FoodCorp'),NULL,NULL,'sampled')

mysql逻辑读高影响_逻辑读、物理读、预读的理解

当我们第一次查询完成后,再次进行查询时,所有请求的数据这时已经在缓存中,SQL SERVER这时只要对缓存进行读取就行了,也就是只用进行逻辑读。

mysql逻辑读高影响_逻辑读、物理读、预读的理解