非聚集索引将部分覆盖 select 查询
Nonclustered indexes will partially cover the select query
我在 SQL 数据库服务器中使用 Include
关键字创建了一个非聚集索引。
请查找我为 FACTORS
table 创建的非聚集索引。
CREATE NONCLUSTERED INDEX [FACTORS_BKEY_PNO_IDX] ON [dbo].[FACTORS]
(
[BATCH_KEY] ASC,
[PART_NO] ASC
)
INCLUDE([FACTOR_NAME],[FACTOR_VALUE],[FACTOR_NAME_ETL],[INDUSTRY],[PROGRAM_ID],[PROGRAM_NAME]) WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
GO
如果我有一个如下所示的 SELECT
查询,我的索引 FACTORS_BKEY_PNO_IDX
会覆盖我的 select 查询。 (我的意思是这个索引会帮助我下面的 select 查询更快地检索记录,还是我需要创建另一个与 INCLUDE
字段完全匹配的索引)。
select
BATCH_KEY ,
FACTOR_NAME ,
FACTOR_VALUE ,
INDUSTRY
PART_NO ,
CREATED_TS ,
FACTOR_NAME_ETL ,
PROGRAM_ID ,
PROGRAM_NAME
from
FACTORS
where BATCH_KEY and PART_NO
order by
PART_NO, FACTOR_NAME, FACTOR_VALUE
由于非聚集索引不包括您的 SELECT 查询中的所有字段(例如,它没有 Industry
),因此它不是覆盖索引。不幸的是,它需要从其他地方获取额外的数据,例如,返回到原始 table.
索引可以在两个主要方面提供帮助
- 包含查询所需的所有列的覆盖索引 - 它可以减少要读取的数据量
- 对数据进行预排序以允许进行索引查找
最快的是当这两种情况都发生时,例如,它被适当地排序并且它是一个覆盖索引。在您的示例中,索引的主要字段看起来是合适的,但它不是覆盖索引。
即使它不是覆盖索引,预排序仍然可以提供帮助,例如,它使用索引来确定要返回到 table 的哪些行以从中获取其余数据。它使用索引的方式很像书中的索引——例如,您使用索引来查找书中的相关页面,然后阅读每一页以获取所需的信息。在这些情况下,较小的索引(例如,仅在 batch_key 和 part_no 上,没有其他字段)将以与您拥有的更广泛的索引相同的方式运行。事实上,较小的索引会 略微 更好,因为它要读取的数据更少(2 列对 8 列):因为无论如何它都必须返回 table 才能获得数据;它也可以从那里获取其他列。
但是,如果索引表明有太多的行,SQL 引擎通常会立即读取整个 table,就好像那里没有索引一样已经.
Brent Ozar 制作了一个非常好的视频,名为 How to think like an SQL Server engine - 如果您使用的是 dbo。我猜您正在使用 SQL 服务器。我强烈推荐观看它,因为我从中学到了很多关于索引等的知识,而且你似乎有很好的基础知识水平,也能学到很多东西。
(PS - 我猜 where BATCH_KEY and PART_NO
只是一个拼写错误)。
我在 SQL 数据库服务器中使用 Include
关键字创建了一个非聚集索引。
请查找我为 FACTORS
table 创建的非聚集索引。
CREATE NONCLUSTERED INDEX [FACTORS_BKEY_PNO_IDX] ON [dbo].[FACTORS]
(
[BATCH_KEY] ASC,
[PART_NO] ASC
)
INCLUDE([FACTOR_NAME],[FACTOR_VALUE],[FACTOR_NAME_ETL],[INDUSTRY],[PROGRAM_ID],[PROGRAM_NAME]) WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
GO
如果我有一个如下所示的 SELECT
查询,我的索引 FACTORS_BKEY_PNO_IDX
会覆盖我的 select 查询。 (我的意思是这个索引会帮助我下面的 select 查询更快地检索记录,还是我需要创建另一个与 INCLUDE
字段完全匹配的索引)。
select
BATCH_KEY ,
FACTOR_NAME ,
FACTOR_VALUE ,
INDUSTRY
PART_NO ,
CREATED_TS ,
FACTOR_NAME_ETL ,
PROGRAM_ID ,
PROGRAM_NAME
from
FACTORS
where BATCH_KEY and PART_NO
order by
PART_NO, FACTOR_NAME, FACTOR_VALUE
由于非聚集索引不包括您的 SELECT 查询中的所有字段(例如,它没有 Industry
),因此它不是覆盖索引。不幸的是,它需要从其他地方获取额外的数据,例如,返回到原始 table.
索引可以在两个主要方面提供帮助
- 包含查询所需的所有列的覆盖索引 - 它可以减少要读取的数据量
- 对数据进行预排序以允许进行索引查找
最快的是当这两种情况都发生时,例如,它被适当地排序并且它是一个覆盖索引。在您的示例中,索引的主要字段看起来是合适的,但它不是覆盖索引。
即使它不是覆盖索引,预排序仍然可以提供帮助,例如,它使用索引来确定要返回到 table 的哪些行以从中获取其余数据。它使用索引的方式很像书中的索引——例如,您使用索引来查找书中的相关页面,然后阅读每一页以获取所需的信息。在这些情况下,较小的索引(例如,仅在 batch_key 和 part_no 上,没有其他字段)将以与您拥有的更广泛的索引相同的方式运行。事实上,较小的索引会 略微 更好,因为它要读取的数据更少(2 列对 8 列):因为无论如何它都必须返回 table 才能获得数据;它也可以从那里获取其他列。
但是,如果索引表明有太多的行,SQL 引擎通常会立即读取整个 table,就好像那里没有索引一样已经.
Brent Ozar 制作了一个非常好的视频,名为 How to think like an SQL Server engine - 如果您使用的是 dbo。我猜您正在使用 SQL 服务器。我强烈推荐观看它,因为我从中学到了很多关于索引等的知识,而且你似乎有很好的基础知识水平,也能学到很多东西。
(PS - 我猜 where BATCH_KEY and PART_NO
只是一个拼写错误)。