table 上包含 200+ 百万行的索引

Included index on table with 200+ million rows

我在 table 上创建包含略多于 2 亿条记录的索引时遇到困难。 table的结构如下:

    [Id] [int] IDENTITY(1,1) NOT NULL,
  [Name] [nvarchar](60) NOT NULL,
 [VatId] [int] NOT NULL,
[UserId] [int] NULL,
..some additional [int] columns

问题是当我执行以下查询时:

set statistics time on;

 select top 20 [Id] from tblArticle where UserId = 7 order by Id desc;

set statistics time off;

..然后在 ~27 毫秒内检索结果(UserId 列上有一个 non-clustered index)。

然而,当我尝试 select 额外的列时,例如:

set statistics time on;

 select top 20 [Id], [VatId] from tblArticle where UserId = 8 order by Id desc;

set statistics time off;

..然后结果在 ~2,000 毫秒后返回。

查看执行计划: ..很明显,Key Lookup 在这里花费的时间最多。

我尝试在 VatId 上创建包含索引,例如:

CREATE NONCLUSTERED INDEX [NonClusteredIndex-UserIdIncVatId] ON [dbo].[tblArticle]
(
    [UserId] ASC
)
INCLUDE ([VatId]) 
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
      SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, 
      ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)

..但在 运行 几个小时后,此查询以错误

结束

Insufficient memory in pool (default)

(我的 SQL 服务器实例运行在 8GB RAM,Core i7 上)

我的问题:是否有任何其他可能的技巧来摆脱这个 Clustered Key Lookup 并提高性能?

非常感谢

编辑:Id 具有聚集索引。

调用 set statistics io on; 产生以下结果:

Table 'tblArticle'. 
Scan count 1, 
logical reads 730, 
physical reads 1, 
read-ahead reads 1351, 
lob logical reads 0, 
lob physical reads 0, 
lob read-ahead reads 0.

编辑 2: 只是为了制作完整的图片,带有提示的执行计划:

尝试:

WITH cte AS (
    select top 20 [Id] 
    from tblArticle 
    where UserId = 7 
    order by Id desc
)
SELECT t.[Id], t.[VatId]
FROM tblArticle t
JOIN cte 
  ON cte.[Id]= t.[Id]

另外我刚从另一个问题中得到建议创建一个复合索引可能会有所帮助因为不需要查找

oracle Update comparing Varchar