У меня есть эта довольно простая таблица с 17m записями:
CREATE TABLE [dbo].[LineNumbers](
[Id] [int] IDENTITY(1,1) NOT NULL,
[LineDescriptionId] [int] NOT NULL,
[ProtocolId] [int] NULL,
[Value] [int] NULL,
CONSTRAINT [PK_LineNumbers] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
Запрос к таблице с дополнительным объединением работает нормально, если в ней нет ProtocolId
:
select top 1
ln.LineDescriptionId
from LineNumbers ln
join LineDescriptions ld on ld.Id = ln.LineDescriptionId and ld.ProtocolSetId = 25
-- Elapsed time: 00:00:00.1718750
План выполнения: https://www.brentozar.com/pastetheplan/?id=rJV34gvR7
Но когда я пытаюсь добавить ProtocolId
в список полей, время запроса резко увеличивается:
select top 1
ln.ProtocolId
from LineNumbers ln
join LineDescriptions ld on ld.Id = ln.LineDescriptionId and ld.ProtocolSetId = 25
-- Elapsed time: 00:02:19.6464843
План выполнения: https://www.brentozar.com/pastetheplan/?id=SkG-hyDCQ
Кроме того, это работает гладко:
select top 1
(select ProtocolId from LineNumbers where LineNumbers.Id = ln.Id) as ProtocolId
from LineNumbers ln
join LineDescriptions ld on ld.Id = ln.LineDescriptionId and ld.ProtocolSetId = 25
-- Elapsed time: 00:00:00.1718750
Пробовал эти запросы и варианты в БД Azure и локальном MSSQL 2017. Результаты совпадают.Пока я держу ProtocolId
вне списка полей, все в порядке.
Есть ли какая-то ошибка в моей схеме данных (все было создано с помощью миграций Entity Framework)?
CREATE TABLE [dbo].[LineNumbers](
[Id] [int] IDENTITY(1,1) NOT NULL,
[LineDescriptionId] [int] NOT NULL,
[ProtocolId] [int] NULL,
[Value] [int] NULL,
CONSTRAINT [PK_LineNumbers] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Index [IX_LineNumbers_LineDescriptionId] Script Date: 21.11.2018 10:47:09 ******/
CREATE NONCLUSTERED INDEX [IX_LineNumbers_LineDescriptionId] ON [dbo].[LineNumbers]
(
[LineDescriptionId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/****** Object: Index [IX_LineNumbers_LineDescriptionId_Value] Script Date: 21.11.2018 10:47:09 ******/
CREATE NONCLUSTERED INDEX [IX_LineNumbers_LineDescriptionId_Value] ON [dbo].[LineNumbers]
(
[LineDescriptionId] ASC,
[Value] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
/****** Object: Index [IX_LineNumbers_ProtocolId] Script Date: 21.11.2018 10:47:09 ******/
CREATE NONCLUSTERED INDEX [IX_LineNumbers_ProtocolId] ON [dbo].[LineNumbers]
(
[ProtocolId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE [dbo].[LineNumbers] WITH NOCHECK ADD CONSTRAINT [FK_LineNumbers_LineDescriptions_LineDescriptionId] FOREIGN KEY([LineDescriptionId])
REFERENCES [dbo].[LineDescriptions] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[LineNumbers] CHECK CONSTRAINT [FK_LineNumbers_LineDescriptions_LineDescriptionId]
GO
ALTER TABLE [dbo].[LineNumbers] WITH NOCHECK ADD CONSTRAINT [FK_LineNumbers_Protocols_ProtocolId] FOREIGN KEY([ProtocolId])
REFERENCES [dbo].[Protocols] ([Id])
GO
ALTER TABLE [dbo].[LineNumbers] CHECK CONSTRAINT [FK_LineNumbers_Protocols_ProtocolId]
GO