【问题标题】:Trying to understand sql execution plan试图理解sql执行计划
【发布时间】:2011-09-08 16:51:58
【问题描述】:

我在 SQL Server 中创建了一个简单的表:

MemberId INT PRIMARY KEY Identity
Name NVARCHAR(100) NULL
Description NVARCHAR(250) NULL

当我创建 MemberId 作为主键时,唯一添加的索引是聚集索引。我没有为名称或描述添加索引。

我向表中添加了大约 30,000 行测试数据并进行了以下查询:

SELECT * FROM Members WHERE Name = 'Foo'

执行计划如下:

Clustered Index Scan - cost 100%

这是如何进行聚集索引扫描的?我不是在预测聚集索引。我认为这更像是表扫描。谁可以给我解释一下这个?如果不这样做,究竟会导致表扫描?

【问题讨论】:

  • 如果按名称搜索将成为一个常见要求,您应该尝试在该列上创建一个具有非聚集索引的相同表,用相同的 30,000 行填充它,然后运行查询对照每张桌子,并比较这些计划。您应该会看到一个非聚集索引搜索,并且它应该更有效(至少对于这个查询)。

标签: sql-server sql-execution-plan


【解决方案1】:

如果表有聚集索引,clustered index scan 等同于全表扫描。聚集索引本身包含所有数据。

【讨论】:

  • 所以如果你的表有很多行,聚集索引扫描的性能就不好?如果我有 5000 万行并运行此查询,它的性能可能会很差?我将如何修改此表/查询,以便出于好奇看到表扫描?
  • 当然,如果您在name 列上没有索引,它将扫描所有行。
  • 我相信你需要删除 pk 约束,然后 pk,然后将 pk 创建为非集群。所以你会有堆表,clustered index scan 会变成table scan
  • 表扫描或聚集索引扫描是微软的术语。如果表包含聚集索引,您将获得聚集索引扫描。如果没有,它就是一个堆,你会得到一个表扫描。 Name 上的非聚集索引应该为您提供一个计划,其中包含非聚集查找和聚集的键查找。
【解决方案2】:

如果你用这个改变你的主键声明

MemberId INT PRIMARY KEY NONCLUSTERED IDENTITY

你会发现表 scan 直到没有聚集索引。创建聚集索引后,您的表结构将发生变化,并按聚集索引键进行物理排序。我认为表扫描并不意味着在那之后,而是用聚集索引扫描代替。每当没有找到有用的索引来覆盖查询时

换句话说,表扫描只有在表数据未聚集并存储为heap structure时才有意义

What's the difference between a Table Scan and a Clustered Index Scan?

【讨论】:

  • 堆最佳实践是从什么时候开始的?并且聚集索引扫描是一种表扫描。
  • 这不是最佳实践。他正在尝试了解 sql 执行计划并正在寻找丢失的表扫描。我认为这对他找到表扫描会有所帮助,
猜你喜欢
  • 2017-03-05
  • 2021-12-09
  • 2016-12-09
  • 1970-01-01
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多