Я боролся с этим некоторое время.
У меня есть база данных с тремя таблицами (каждая из которых содержит миллионы записей) следующим образом (для простоты удалены некоторые столбцы):
1.[Entity]
[Id] UNIQUEIDENTIFIER PK,
[EntityLevel_Id] UNIQUEIDENTIFIER NOT NULL FK [EntityLevel] ([Id])
2.[EntityData]
[Id] UNIQUEIDENTIFIER PK,
[Entity_Id] UNIQUEIDENTIFIER NOT NULL FK [Entity] ([Id]),
[DataLanguage_Id] UNIQUEIDENTIFIER NOT NULL FK [Language] ([Id]),
[Code] NVARCHAR (250) NOT NULL
3.[EntityLevel]
[Id] UNIQUEIDENTIFIER PK,
[Sort] INT NOT NULL
Существуют индексы следующим образом
[IX_Entity_EntityLevelId] ON [Entity] ([EntityLevel_Id])
[IX_EntityData_EntityId] ON [EntityData] ([Entity_Id])
[IX_EntityData_DataLanguageId_Code] ON [EntityData] ([DataLanguage_Id], [Code])
[IX_EntityLevel_Sort] ON [EntityLevel] ([Sort])
Чтобы исключить вероятность того, что медлительность связана с выбранными столбцами, я выбираю только фиксированное значение.
Следующий запрос выполняется очень быстро (менее 1 секунды):
SELECT TOP 20
1
FROM
[Entity]
INNER JOIN [EntityData] ON [Entity].[Id] = [EntityData].[Entity_Id]
INNER JOIN [EntityLevel] ON [Entity].[EntityLevel_Id] = [EntityLevel].[Id]
WHERE
[EntityData].[DataLanguage_Id] = 'B6930015-F177-4ED3-97B0-AAEF401F9265'
Следующий запрос также выполняется очень быстро:
SELECT TOP 20
1
FROM
[Entity]
INNER JOIN [EntityData] ON [Entity].[Id] = [EntityData].[Entity_Id]
INNER JOIN [EntityLevel] ON [Entity].[EntityLevel_Id] = [EntityLevel].[Id]
WHERE
[EntityData].[DataLanguage_Id] = 'B6930015-F177-4ED3-97B0-AAEF401F9265'
ORDER BY
[EntityData].[Code] ASC
И следующее также работает быстро:
SELECT TOP 20
1
FROM
[Entity]
INNER JOIN [EntityData] ON [Entity].[Id] = [EntityData].[Entity_Id]
INNER JOIN [EntityLevel] ON [Entity].[EntityLevel_Id] = [EntityLevel].[Id]
WHERE
[EntityLevel].[Sort] = 1
НО, следующий запрос выполняется ОЧЕНЬ МЕДЛЕННО (примерно 10 секунд):
SELECT TOP 20
1
FROM
[Entity]
INNER JOIN [EntityData] ON [Entity].[Id] = [EntityData].[Entity_Id]
INNER JOIN [EntityLevel] ON [Entity].[EntityLevel_Id] = [EntityLevel].[Id]
WHERE
[EntityData].[DataLanguage_Id] = 'B6930015-F177-4ED3-97B0-AAEF401F9265'
AND
[EntityLevel].[Sort] = 1
ORDER BY
[EntityData].[Code]
Я не знаю причину, и я не нахожу способа применить дополнительные индексы, чтобы запрос выполнялся быстрее.
Любая помощь приветствуется!
Изменить: следующие запросы также выполняются быстро:
SELECT TOP 20
1
FROM
[Entity]
INNER JOIN [EntityData] ON [Entity].[Id] = [EntityData].[Entity_Id]
INNER JOIN [EntityLevel] ON [Entity].[EntityLevel_Id] = [EntityLevel].[Id]
WHERE
[EntityData].[DataLanguage_Id] = 'B6930015-F177-4ED3-97B0-AAEF401F9265'
AND
[EntityLevel].[Sort] = 1
А также
SELECT TOP 20
1
FROM
[Entity]
INNER JOIN [EntityData] ON [Entity].[Id] = [EntityData].[Entity_Id]
INNER JOIN [EntityLevel] ON [Entity].[EntityLevel_Id] = [EntityLevel].[Id]
WHERE
[EntityLevel].[Sort] = 1
ORDER BY
[EntityData].[Code]
Проблема появляется только с заказом и двумя фильтрами
[EntityLevel_Id]
. И тогда есть вероятность, что при изменении порядка, как я уже упоминал,([EntityLevel_Id], [Id])
будет лучшим вариантом. Кластерный индекс вообще не покрывает этого. 29.03.2020