索引查找和表扫描执行时间相同

时间:2018-10-24 15:07:48

标签: sql sql-server tsql indexing

我有一个表,其结构如下:

CREATE TABLE [dbo].[User]
(
    [Id] [INT] IDENTITY(1,1) NOT NULL,
    [CountryCode] [NVARCHAR](2) NOT NULL DEFAULT (N'GB'),
    [CreationDate] [DATETIME2](7) NOT NULL,
    [Email] [NVARCHAR](256) NULL,
    [EmailConfirmed] [BIT] NOT NULL,
    [FirstName] [NVARCHAR](MAX) NOT NULL,
    [LastName] [NVARCHAR](MAX) NOT NULL,
    [LastSignIn] [DATETIME2](7) NOT NULL,
    [LockoutEnabled] [BIT] NOT NULL,
    [LockoutEnd] [DATETIMEOFFSET](7) NULL,
    [NormalizedEmail] [NVARCHAR](256) NULL,
    [NormalizedUserName] [NVARCHAR](256) NULL,
    [PasswordHash] [NVARCHAR](MAX) NULL,
    [SecurityStamp] [NVARCHAR](MAX) NULL,
    [TimeZone] [NVARCHAR](64) NOT NULL DEFAULT (N'Europe/London'),
    [TwoFactorEnabled] [BIT] NOT NULL,
    [UserName] [NVARCHAR](256) NULL,
    [LastInfoUpdate] [DATETIME] NOT NULL
)

该表中大约有一百万行,我想对[LastInfoUpdate]列应用非聚集索引。

因此,我使用以下命令创建了非聚集索引:

CREATE NONCLUSTERED INDEX IX_ProductVendor_VendorID1   
ON [dbo].[TestUsers] (LastInfoUpdate)
INCLUDE(Email)

一旦我尝试运行这样的简单查询:

  SELECT [LastInfoUpdate]
  FROM [dbo].[TestUsers]
  WHERE [LastInfoUpdate] >= GETUTCDATE()

我得到的时间与没有索引的时间相同。根据具有db的SQL Server Profiler的说明,使用索引时会进行索引查找,与没有索引的情况相比,它只使用较少的cpu资源,但这对我来说很重要。几点都一样?我在做什么错了?

Execution Plan of table scan

Execution plan of Index Scan

Index seek Execution Plan file

3 个答案:

答案 0 :(得分:1)

只需创建以下索引:

CREATE INDEX IX_Users_EventDate ON Users(EventDate)
INCLUDE (EventId)

以下查询将很快:

SELECT EventId, EventDate
FROM Users
WHERE EventDate <= GETUTCDATE()

因为索引是覆盖索引。

覆盖索引的键必须包含WHEREORDER BY子句中引用的列。并且覆盖索引必须包括SELECT列表中引用的所有列。

您发布的查询与您链接的查询计划不匹配。查询计划适用于上述查询。

要考虑的另一件事是查询返回的记录数。如果数量很多,查询将不能足够快,因为它需要读取所有数据并将其发送到网络。

答案 1 :(得分:0)

尝试使用ColumnStore索引。当您想要获得一定范围的列时,它会更快:

CREATE NONCLUSTERED COLUMNSTORE INDEX 
    [csi_User_LastInfoUpdate_Email] ON 
    [dbo].[User] ( [LastInfoUpdate], [Email] )WITH 
    (DROP_EXISTING = OFF, COMPRESSION_DELAY = 0) ON [PRIMARY]

An article about column store index.

答案 2 :(得分:0)

“ [LastInfoUpdate]> = GETUTCDATE()”可能会返回很多结果。在这种情况下,Tablescan可以比索引查找和随后从tabledata中添加信息的速度更快。 通过将查询的信息添加到索引中,可以避免对表数据进行昂贵的后续查找。