试图理解sql执行计划
Posted
技术标签:
【中文标题】试图理解sql执行计划【英文标题】:Trying to understand sql execution plan 【发布时间】: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 行填充它,然后运行查询对照每张桌子,并比较这些计划。您应该会看到一个非聚集索引搜索,并且它应该更有效(至少对于这个查询)。 【参考方案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 执行计划并正在寻找丢失的表扫描。我认为这对他找到表扫描会有所帮助,以上是关于试图理解sql执行计划的主要内容,如果未能解决你的问题,请参考以下文章