你能解释微软SQL Server中覆盖索引和涵盖查询的概念和关系吗?
覆盖索引是可以满足查询中所有请求的列而不执行对聚簇索引的进一步查找的索引.
没有覆盖查询这样的东西.
看看这篇Simple-Talk文章:使用覆盖索引来提高查询性能.
如果查询列表中请求的所有列select
都在索引中可用,则查询引擎不必再次查找表,这可以显着提高查询的性能.由于索引中的所有请求列都可用,因此索引覆盖了查询.因此,查询称为覆盖查询,索引是覆盖索引.
如果选择列表中的列来自同一个表,则聚簇索引始终可以覆盖查询.
如果您不熟悉索引概念,以下链接可能会有所帮助:
关于索引和覆盖查询和索引的优缺点的优秀视频.
SQL Server中的索引
覆盖指数是Non-Clustered
指数.Clustered和Non-Clustered索引都使用B-Tree数据结构来改进对数据的搜索,不同之处在于,在Clustered Index的叶子中,整个记录(即行)在物理上存储在那里!,但这不是非聚集索引的情况.以下示例说明了这一点:
示例:我有一个包含三列的表:ID,Fname和Lname.
但是,对于非聚集索引,有两种可能:表已经具有聚簇索引,或者它没有:
如这两个图所示,这样的非聚集索引不能提供良好的性能,因为它们无法仅从B树中找到喜欢的值(即Lname).相反,他们必须执行额外的查找步骤(Key或RID查找)以查找Lname的值.而且,这是覆盖索引进入屏幕的地方.这里,ID上的Non-Clustered索引在B-Tree的叶子中紧挨着它的Lname值,并且不再需要任何类型的查找.
一个覆盖查询是其中在查询的结果集中的所有列从非聚集索引拉查询.
通过明智的索引排列,查询被覆盖的查询.
覆盖查询通常比非覆盖查询更具性能,部分原因是非聚集索引每页的行数多于聚簇索引或堆索引,因此需要将更少的页面带入内存以满足查询.它们每页有更多行,因为只有部分表行是索引行的一部分.
甲覆盖索引是其在覆盖查询中使用的索引.没有索引这样的东西本身就是覆盖索引.索引可以是关于查询A的覆盖索引,而同时不是关于查询B的覆盖索引.
以下是devx.com上的一篇文章:
创建一个包含SQL查询中使用的所有列的非聚集索引,这种技术称为索引覆盖
我只能假设一个被覆盖的查询是一个查询,其索引覆盖了其返回记录集中的所有列.一个警告 - 必须构建索引和查询,以允许SQL服务器从查询中实际推断索引是有用的.
例如,表的连接本身可能无法从这样的索引中受益(取决于SQL查询执行计划程序的智能):
PersonID ParentID Name 1 NULL Abe 2 NULL Bob 3 1 Carl 4 2 Dave
让我们假设有一个索引PersonID,ParentID,Name
- 这将是一个查询的覆盖索引,如:
SELECT PersonID, ParentID, Name FROM MyTable
但是像这样的查询:
SELECT PersonID, Name FROM MyTable LEFT JOIN MyTable T ON T.PersonID=MyTable.ParentID
即使所有列都在索引中,也可能不会那么有利.为什么?因为你并没有真正告诉它你想要使用三重索引PersonID,ParentID,Name
.
相反,你正在建立一个基于两列的条件 - PersonID
并且ParentID
(遗漏了Name
)然后你要求所有记录和列PersonID, Name
.实际上,根据实施情况,索引可能有助于后者.但是对于第一部分,你最好还有其他索引.