Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 为什么非聚集索引扫描比聚集索引扫描快?_Sql_Sql Server_Indexing_Sql Execution Plan_Full Table Scan - Fatal编程技术网

Sql 为什么非聚集索引扫描比聚集索引扫描快?

Sql 为什么非聚集索引扫描比聚集索引扫描快?,sql,sql-server,indexing,sql-execution-plan,full-table-scan,Sql,Sql Server,Indexing,Sql Execution Plan,Full Table Scan,正如我所知,堆表是没有聚集索引的表,并且没有物理顺序。 我有一个120k行的堆表“扫描”,我使用这个选择: SELECT id FROM scan 如果我为列“id”创建一个非聚集索引,我将得到223次物理读取。 如果我删除非聚集索引并更改表以使“id”成为主键(以及我的聚集索引),我将获得515次物理读取 如果聚集索引表类似于下图: 为什么聚集索引扫描像表扫描一样工作?(检索所有行时情况更糟)。为什么不使用“聚集索引表”,因为它具有更少的块,并且已经具有我需要的ID?聚集索引通常与堆中的相

正如我所知,堆表是没有聚集索引的表,并且没有物理顺序。 我有一个120k行的堆表“扫描”,我使用这个选择:

SELECT id FROM scan
如果我为列“id”创建一个非聚集索引,我将得到223次物理读取。 如果我删除非聚集索引并更改表以使“id”成为主键(以及我的聚集索引),我将获得515次物理读取

如果聚集索引表类似于下图:


为什么聚集索引扫描像表扫描一样工作?(检索所有行时情况更糟)。为什么不使用“聚集索引表”,因为它具有更少的块,并且已经具有我需要的ID?

聚集索引通常与堆中的相同数据一样大(假设页面已满)。由于额外的B树级别,它应该使用比堆多一点的读取

CI不能小于堆的大小。我不明白你为什么会这样想。分区(无论是堆还是树)的大部分大小都在数据中

请注意,较少的物理读取并不一定转化为更快的查询。随机IO可以比顺序IO慢100倍。

尝试运行

DBCC DROPCLEANBUFFERS
在查询之前

如果你真的想比较的话。
优化查询时,物理读取并不意味着与逻辑读取相同

SQL Server索引是b树。非聚集索引只包含索引列,b树的叶节点是指向相应数据页的指针。聚集索引是不同的:它的叶节点是数据页本身,聚集索引的b树成为表本身的后备存储;该表的堆不再存在

非聚集索引包含一个可能是整数的单列。这是一个小而紧凑的索引。您的查询
selectid fromscan
有一个覆盖索引:只需检查索引即可满足查询,这就是正在发生的情况。但是,如果您的查询包含不在索引中的列,假设优化器选择使用非聚集索引,则需要额外的查找来从聚集索引或堆中获取所需的数据页

要了解发生了什么,您需要检查优化器选择的执行计划:

  • 见格兰特·弗里奇的《红门》

何时使用聚集索引-

查询注意事项:

1) 通过使用诸如介于、>、>=之间的运算符返回一系列值,因为他的表似乎只有4MB大小,我想我们可以假设他这样做了。如果不是,他就不会收到一次物理读取。usr的观点很好,但我不确定在alter table命令之后是否维护了表的缓存数据……这张图片真的代表了聚集索引(指针指向其余行)?或者只是非聚集索引是这样的?如果最后一个是正确的,我可以理解为什么NCI比CIT工作得更好问题是聚集索引扫描使用的物理读取数与表扫描相同。在这种情况下,为什么非聚集索引扫描比聚集索引扫描运行得更快?我在第一段中解释了这一点。你到底不明白什么?为什么您认为CI扫描应该更快?我想这是我的疑问:图片是否真的表示聚集索引(指针指向其余行)?或者只是非聚集索引是这样的?如果最后一个是正确的,我可以理解为什么NCI比CIT工作得更好CI包含所有内联列。NCI只包含您指定的列和所有CI键列。明白了。我的错误是认为非聚集索引和聚集索引的b-树是等效的。@Mucida:这两种索引的b-树(导航树)大体上是等效的-显著不同的是树中的叶级节点…@marc_s,但是当我在表中同时有一个Clsutered索引和一个非Clsutered索引时,非聚集b-树的叶子会发生变化并包含聚集索引?当我选择这两个索引列时,它们似乎运行得很快,甚至是使用非聚集索引的执行计划scan@Mucida:是的,这正是我试图解释的:两种索引类型的导航树大致相同-带有索引列的b树。叶级别非常不同:聚集索引的实际数据页,非聚集索引包含索引列,加上聚集索引列(如果存在聚集索引,或者如果不存在聚集索引,RID=行标识符)