我有两个表 [LogTable] 和 [LogTable_Cross]。
下面是填充它们的模式和脚本:
--Main Table
CREATE TABLE [dbo].[LogTable]
(
[LogID] [int] NOT NULL
IDENTITY(1, 1) ,
[DateSent] [datetime] NULL,
)
ON [PRIMARY]
GO
ALTER TABLE [dbo].[LogTable] ADD CONSTRAINT [PK_LogTable] PRIMARY KEY CLUSTERED ([LogID]) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_LogTable_DateSent] ON [dbo].[LogTable] ([DateSent] DESC) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_LogTable_DateSent_LogID] ON [dbo].[LogTable] ([DateSent] DESC) INCLUDE ([LogID]) ON [PRIMARY]
GO
--Cross table
CREATE TABLE [dbo].[LogTable_Cross]
(
[LogID] [int] NOT NULL ,
[UserID] [int] NOT NULL
)
ON [PRIMARY]
GO
ALTER TABLE [dbo].[LogTable_Cross] WITH NOCHECK ADD CONSTRAINT [FK_LogTable_Cross_LogTable] FOREIGN KEY ([LogID]) REFERENCES [dbo].[LogTable] ([LogID])
GO
CREATE NONCLUSTERED INDEX [IX_LogTable_Cross_UserID_LogID]
ON [dbo].[LogTable_Cross] ([UserID])
INCLUDE ([LogID])
GO
-- Script to populate them
INSERT INTO [LogTable]
SELECT TOP 100000
DATEADD(day, ( ABS(CHECKSUM(NEWID())) % 65530 ), 0)
FROM sys.sysobjects
CROSS JOIN sys.all_columns
INSERT INTO [LogTable_Cross]
SELECT [LogID] ,
1
FROM [LogTable]
ORDER BY NEWID()
INSERT INTO [LogTable_Cross]
SELECT [LogID] ,
2
FROM [LogTable]
ORDER BY NEWID()
INSERT INTO [LogTable_Cross]
SELECT [LogID] ,
3
FROM [LogTable]
ORDER BY NEWID()
GO
我想选择所有那些给定用户ID的日志(来自LogTable)(用户ID将从交叉表LogTable_Cross中检查),日期为desc。
SELECT DI.LogID
FROM LogTable DI
INNER JOIN LogTable_Cross DP ON DP.LogID = DI.LogID
WHERE DP.UserID = 1
ORDER BY DateSent DESC
如您所见,有一个排序运算符起作用,这可能是因为以下行“ORDER BY DateSent DESC”
我的问题是,即使我在表上应用了以下索引,为什么该 Sort 运算符仍会出现在计划中
GO
CREATE NONCLUSTERED INDEX [IX_LogTable_DateSent] ON [dbo].[LogTable] ([DateSent] DESC) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [IX_LogTable_DateSent_LogID] ON [dbo].[LogTable] ([DateSent] DESC) INCLUDE ([LogID]) ON [PRIMARY]
GO
另一方面,如果我删除连接并以这种方式编写查询:
SELECT DI.LogID
FROM LogTable DI
-- INNER JOIN LogTable_Cross DP ON DP.LogID = DI.LogID
--WHERE DP.UserID = 1
ORDER BY DateSent DESC
计划更改为
即排序运算符被删除,计划显示我的查询正在使用我的非聚集索引。
即使我正在使用联接,这也是一种在我的查询计划中删除“排序”运算符的方法。
编辑:
我更进一步,将“最大并行度”限制为 1
再次运行以下查询:
SELECT DI.LogID
FROM LogTable DI
INNER JOIN LogTable_Cross DP ON DP.LogID = DI.LogID
WHERE DP.UserID = 1
ORDER BY DateSent DESC
并且该计划仍然具有该 Sort 运算符:
编辑 2
即使我有以下建议的索引:
CREATE NONCLUSTERED INDEX [IX_LogTable_Cross_UserID_LogID_2]
ON [dbo].[LogTable_Cross] ([UserID], [LogID])