包含2亿多行的表格中包含的索引

时间:2015-11-03 16:28:46

标签: sql sql-server query-performance query-tuning

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

    [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;

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

但是,当我尝试选择其他列时,例如:

set statistics time on;

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

set statistics time off;

..然后结果回到~2000ms。

查看执行计划: enter image description here ..显然,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)

..但运行几个小时后,此查询最终会出现错误

  

池中的内存不足(默认)

(我的SQL Server实例在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: 只是为了全面了解,执行计划提示: enter image description here

1 个答案:

答案 0 :(得分:1)

尝试:

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