首页 文章

需要一些帮助理解IO统计

提问于
浏览
0

我有一个查询在执行计划中有一个非常昂贵的INDEX SEEK操作 . 为了追踪原因,我设置了IO STATISTICS并运行它 . 在问题部分,它提供了以下统计信息:

表'#TempStudents_Enrollment2 _________________________________________________________________ 000000004D5F' . 扫描计数0,逻辑读取60,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'工作表' . 扫描计数0,逻辑读取0,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'#TempRace2 ________________________________________________________________________________ 000000004D58' . 扫描计数1,逻辑读取1,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'工作表' . 扫描计数0,逻辑读取0,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'RefRace' . 扫描计数120,逻辑读取240,物理读取1,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'RefFedEnctyRaceCatg' . 扫描计数18,逻辑读取36,物理读取2,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'#43B0BA0F' . 扫描计数1,逻辑读取60,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'#42BC95D6' . 扫描计数1,逻辑读取60,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'#41C8719D' . 扫描计数1,逻辑读取60,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'#40D44D64' . 扫描计数1,逻辑读取60,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'#LEA2 ______________________________________________________________________________________ 000000004D56' . 扫描计数1,逻辑读取60,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'#39332B9C' . 扫描计数1,逻辑读取60,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'#School2 __________________________________________________________________________________ 000000004D57' . 扫描计数1,逻辑读取29164,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'#GenderKey ________________________________________________________________________________ 000000004D5A' . 扫描计数1,逻辑读取29164,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'#LangAcqKey _______________________________________________________________________________ 000000004D5B' . 扫描计数1,逻辑读取29164,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'#TransferCatKey ___________________________________________________________________________________000000004D5C' . 扫描计数1,逻辑读取29164,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'#ResCatKey ________________________________________________________________________________ 000000004D5D' . 扫描计数1,逻辑读取29164,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'RPT_SnapShot_1_4_StuPgm_Denorm' . 扫描计数2344954,逻辑读取4992518,物理读取16,预读读取8,lob逻辑读取0,lob物理读取0,lob预读读取0.表'#3FE0292B' . 扫描计数1,逻辑读取2344954,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读取读取0.表'RPT_SnapShot_1_4_StuEnrlmt_Denorm' . 扫描计数20,逻辑读取87679,物理读取0,预读读取87425,lob逻辑读取0,lob物理读取0,lob预读读取0.表'#GradeKey _____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________扫描计数1,逻辑读取1,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0 .

当我想提高性能时,我应该在这里寻找什么?扫描计数超过200万的线看起来很可疑,但我真的不知道 . 有没有人在这里看到任何我应该更详细研究的内容?

4 回答

  • 2

    似乎那里有一个相当昂贵的指数 scanTable 'RPT_SnapShot_1_4_StuPgm_Denorm'. Scan count 2344954, logical reads 4992518 .

  • 1

    来源:MS SQL Server 2008 R2 Unleashed

    Scan Count 扫描计数值指示在查询执行期间访问相应表的次数 . 外表嵌套循环连接的扫描计数通常为1.内部表的扫描计数通常反映内部表的搜索次数,这通常与外部表中的合格行数相同 . 内部表的逻辑读取数等于扫描计数乘以每次扫描的每次查找的页数 . 请注意,如果SQL Server将所需的行从内部表复制到高速缓存内存中的工作表中,并从工作表中读取以用于后续迭代,则内部表的扫描计数有时可能仅为嵌套连接的扫描计数(例如,如果它使用Table Spool操作) . 对于连接中涉及的两个表,散列连接和合并连接的扫描计数通常为1,但这些类型的连接的逻辑读取通常要高得多 .

    Logical Reads 逻辑读取值指示处理查询所需的页面访问总数 . 即使首先必须从磁盘读取,也会从高速缓存中读取每个页面 . 每个物理读取始终具有相应的逻辑读取,因此物理读取的数量永远不会超过逻辑读取的数量 . 由于可能会多次访问同一页面,因此表的逻辑读取次数可能会超过表中的总页数 .

    Physical Reads 物理读取值表示从磁盘读取的实际页数 . 物理读取的值可能会有很大差异,并且随后执行查询会减少或降至零,因为数据将在第一次执行时加载到数据高速缓存中 . 读取机制带入内存的页面也会降低物理读取次数 .

    Read-Ahead Reads 预读读取值表示在处理查询时使用预读机制读入高速缓存的页数 . 由预读机制读取的页面不一定会被查询使用 . 当查询访问由预读机制读取的页面时,它计为逻辑读取,但不计为物理读取机制可以被视为物理I / O的乐观形式,读取页面在查询需要它之前,它需要查询所需的缓存内存 . 在扫描表或索引时,将查看表的索引分配映射页(IAM)以确定哪些扩展区属于该对象 . 范围包含八个数据页 . 通过单次读取读取范围中的八个页面,并按照它们存储在磁盘上的顺序读取范围 . 如果表分布在多个文件中,则预读机制一次尝试从多达八个文件并行读取,而不是从files.read顺序读取 .

  • 0

    您已执行“ set statistics IO on ". In "查询" menu turn on " Include Actual Execution Plan " and "包含客户端统计信息". Run your query/procedure. In " messages " tab look for highest " Logical reads " number, memorize that table. In "执行计划" tab, look for table you found in step before (usually has highest Cost percentage associated in the plan). If it is " Scan " (table scan or index scan), you are missing appropriate index, or appropriate index has no good statistics. If it is " Seek”,然后您正在寻找的行大量分散在块中 . 你必须在你寻找的专栏上 bring them physically together by creating CLUSTERED index . 这是非常有效的方法 . 没有多少人知道聚集索引是什么 . 花些时间研究它们 . 默认情况下,Sql server会创建群集的主键,大多数人都会这样做 . 在许多情况下,它可能导致性能下降 . 您需要聚簇索引,以按照构建聚簇索引的列对行进行物理分组 . 每个表只能有一个聚簇索引 . 聚簇索引不必是唯一的,不必是PK,可以包含多个列 . 您可以重写查询,例如替换存在于IN,反之亦然,或替换表连接存在 . 没有"fastest"加入方法 . 如果有一个,所有其他类型将自动转换为最快的类型 . 这取决于数据,可用指标,公羊数量等 .

    总是测量,不要假设 . 衡量只是事实 . 对于您设法减少逻辑读取的程度,您成功地优化了查询 . 其他优化将是DBA完成的数据库级别(内存缓存,并行进程,存储系统,检查等待事件等) .

  • 1

    唯一值得担心的是“逻辑阅读” . 物理读取将取决于当前缓存的数据量,每次运行查询时都会更改 .

    扫描计数有时是有说服力的,但并不值得关注 .

    编辑:查看有关这些结果的更多讨论in this post here. "telling"的意思是扫描计数有时可能是"flag",表明SQL正在低效地从该表中检索数据 . 但是当你在优化时尝试不同版本的查询时,我会更加关注我在逻辑读取中可以做出的改进 .

相关问题