sql 服务器中的逻辑读取是什么?如何减少没有逻辑?

what is logical reads in sql server? how to reduce no of logical?

经过我的研究,关于如何加速在 SQL 服务器中执行的查询,大多数资源建议通过使用适当的 where 子句来减少逻辑读取。 我真正感兴趣的是了解 SQL 服务器中的工作流程: 当来自端点用户或外部系统的请求调用存储过程时,以及有关该做和不该做的一些提示。

来自Microsoft SQL Server Documentation(Pages and Extents Architecture -> Reading Pages)有一个很好的定义:

The I/O from an instance of the SQL Server Database Engine includes logical and physical reads. A logical read occurs every time the Database Engine requests a page from the buffer cache. If the page is not currently in the buffer cache, a physical read first copies the page from disk into the cache.

因此,逻辑读取是查询引擎需要读取数据的时候。首先,它在内存中查找。如果页面已经在 SQL 服务器的内存中,那么它将使用它。如果它在内存中找不到它,则会触发物理读取并从磁盘读取数据页。没有后续物理读取的逻辑读取基本上是“缓存命中”。

缓冲区缓存(也称为缓冲池)是SQL 服务器用于解决查询的主要工作内存。当您设置 SQL 服务器将使用的内存量时,您正在控制可用缓冲区缓存的大小。

然而,在没有看到查询或不知道 table 包含什么、数据是什么样子以及数据是如何被索引和组织的情况下告诉你你需要做什么基本上是不可能的。

大量的逻辑读取不一定是坏的——或者更确切地说,不一定preventable。糟糕的是 inordinate 数量的逻辑读取。如果您要 return 处理 3 行数据,但查询引擎必须扫描 table 的 2 亿行才能执行此操作,那将非常慢,您可以通过重写来改进它查询或添加索引。

我首先要了解存储过程中的查询有多复杂。值得注意的是,我会寻找缺失的索引。如果您是 运行 SELECT * FROM BigTable WHERE ProductDate >= '01/01/2014',那么我会查看 ProductDate 上是否有索引。但是,如果你是 运行 SELECT * FROM BigTable ORDER BY ProductDate DESC,那么,是的,索引仍然有帮助,但你仍然需要 return 整个数据集,所以你必须阅读整个table 无论如何。此外,请注意,逻辑读取指的是 page 读取,因此如果所讨论的 ProductDate 均匀分布在磁盘周围,您可能需要读取每一页或几乎每一页.

除此之外,可能是 table 上的统计数据已过时。如果您已将 20,000 行添加到 table 并且 SQL 服务器仍然认为那里只有 2000 行,它将完全抛出查询计划。

逻辑读取是指您正在从数据库中读取的记录。让我们举一个愚蠢的小例子:

select *
from
(
  select *
  from orders
  where client = 1234
)
where item = 9876;

在这里你 select 来自客户 1234 的所有订单。然后你只接受项目 9876 的那些。所以(假设优化器没有看到这个并在内部优化你的查询)你 select 第一步中的记录比需要的多得多。通过一步应用这两个标准来减少逻辑读取(以及相应的大中间结果):

select *
from orders
where client = 1234
and item = 9876;

(这也可能会影响物理读取,但不一定必须如此。例如,第一个查询可能会访问 100 条记录,然后将其减少到 10 条,而第二个查询只读取这 10 条记录。但是所有 100 条记录可能在一个磁盘块中,所以两个语句都读取一个磁盘块,即进行一次物理读取。顺便说一句,它甚至可以是零物理读取,以防数据恰好已经在 dbms 缓存中,即在内存中。这还告诉我们物理读取可能因查询而异,而逻辑读取保持不变,只要查询和数据未更改。)