您可以使用这两个查询之一来查看逻辑读取总数和物理读取总数。
SELECT DB_NAME(st.dbid) Db,
OBJECT_NAME(st.objectid, st.dbid) Prc,
qs.execution_count,
qs.total_logical_reads,
qs.total_physical_reads,
qs.statement_start_offset,
qs.statement_end_offset,
st.text
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st;
SELECT DB_NAME(database_id) Db,
OBJECT_NAME(object_id, database_id) Prc,
execution_count,
total_logical_reads,
total_physical_reads
FROM sys.dm_exec_procedure_stats ps;
第一个按语句细分,第二个在整个过程中计数。
物理读取是针对磁盘的,逻辑读取是针对内存的。您可以使用它来确定哪些过程或语句是系统中最昂贵的过程或语句,然后尝试进行调整。
请记住,虽然逻辑读取比物理读取便宜得多,但它们仍然昂贵,因此减少逻辑读取的数量(例如,通过添加适当的索引)可以使查询的运行速度大大提高。
上面的DMV中还有很多其他的列,您可能也会觉得很有趣。
索引如何帮助减少逻辑读取?
在SQL Server中,所有数据都以块为单位组织,大小为8KB。这些块称为“页面”。
每个表都包含“元”页面,这些页面包含有关表结构以及pata页面的信息。如果不存在索引,并且您运行的查询类似SELECT * FROM tbl WHERE Id = 7
SQL Server,则必须在整个表中查找此行或这些行。因此,它一次读取一页,循环遍历每一页中的所有行,以确定适合该WHERE
子句的行。因此,如果该表需要存储1,000,000页,则此查询将执行1,000,000逻辑读取。
如果您有索引,则SQL Server会对页面内的数据进行逻辑排序,并在页面之间建立链接列表。这允许运行带有的运行查询,ORDER BY
而无需进行昂贵的排序操作。但是,更重要的是,对于排序,SQL Server将B + Tree添加到表中。B + Tree是一种与书中的索引可比的结构,在其中查找特定的关键字使我可以直接跳到包含该关键字的页面。典型的书只有一个索引级别,而B + Tree可以有多个。试想一本大书,索引本身就是多页长。在这种情况下,添加一个额外的索引层是有意义的,该索引层告诉我们在夹心页面S
上找到以开头的索引词。
B + Trees被优化为具有尽可能少的级别,同时提供了可以通过在每个索引级别读取一页来找到索引中任何记录的属性。因此,WHERE Id = 7
当您有按排序的索引时,请假设上述查询Id
。假设该索引有5个级别。现在,要查找与此查询匹配的所有记录,我必须在每个索引级别读取一页(即5页)。这称为“索引查找”。如果有多条符合要求的记录,我可能必须按照排序的索引一段时间才能检索所有记录。但让我们假设只有一条记录。
因此,在不运行索引的情况下,该查询需要1,000,000次读取,而indes则需要5次读取。即使逻辑读取是内存中操作,也要花费大量成本-实际上,这是像上面这样的琐碎查询中最昂贵的操作。因此,将所需的逻辑读取量减少200,000倍,将使查询速度提高近一倍。
因此,逻辑读取不等同于表扫描,但是表扫描导致的逻辑读取要比索引查找多得多。