Стратегия индексации - почасовые данные о дизайне таблиц

Я работаю над финансовым проектом и пытаюсь создать таблицу с лучшей стратегией индексации, в которой хранятся почасовые данные, и мне нужно более быстрое извлечение данных. Поскольку это конфиденциально, я объясню на примере таблицы погоды. Если у меня есть таблица ниже

CREATE TABLE [dbo].[WeatherM](
    [WID] [int] IDENTITY(1,1) NOT NULL,
    [CityId] [int] NOT NULL,
    [TempDate] [datetime] NOT NULL,
    [TempF] [decimal](18, 5) NOT NULL,
    [TempC] [decimal](18, 5) NOT NULL,
    [IsActive] [bit] NOT NULL,
    [IsDeleted] [bit] NOT NULL
) ON [PRIMARY]

    ALTER TABLE [dbo].[WeatherM] ADD  CONSTRAINT [DF_WeatherM_IsActive]  DEFAULT ((1)) FOR [IsActive]
    GO
    ALTER TABLE [dbo].[WeatherM] ADD  CONSTRAINT [DF_WeatherM_IsDelete]  DEFAULT ((0)) FOR [IsDeleted]
    GO

Какие индексы были бы лучшими из возможных? У меня есть фильтр предложения where для CityId, TempDate и IsActive.

Мой обычный оператор выбора

SELECT TOP (1000) [WID]
      ,[CityId]  -- Could join with City table and get CityName
      ,[TempDate]
      ,[TempF]  --fahrenheit
      ,[TempC]  --Celcius
      FROM [dbo].[WeatherM] WITH (NOLOCK)
  WHERE CityId = @CityId
  AND TEMPDATE BETWEEN @Date1 and @Date2
  AND IsActive = 1

Каковы наилучшие возможные индексы для более быстрых результатов

Вариант 1. Создание кластеризованного индекса с несколькими столбцами с помощью столбца с предложением where

CREATE CLUSTERED INDEX [IX_WeatherM_1] ON [dbo].[WeatherM]
(
    [CityId] ASC,
    [TempDate] ASC,
    [IsActive] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

- Нужны ли мне дополнительные некластеризованные индексы?

Вариант 2. Создание кластеризованного индекса с несколькими столбцами со столбцами набора результатов и одного некластеризованного индекса со столбцами фильтра

CREATE CLUSTERED INDEX [IX_WeatherM_1] ON [dbo].[WeatherM]
(
    [CityId] ASC,
    [TempDate] ASC,
    [TempC] ASC,
    [TempF] 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

CREATE NONCLUSTERED INDEX [IX_WeatherM] ON [dbo].[WeatherM]
(
    [CityId] ASC,
    [TempDate] ASC,
    [IsActive] 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

Вариант 3: Любой другой?


person ASmith    schedule 24.03.2021    source источник
comment
Вы используете индексы для поддержки ВСЕХ запросов к вашей таблице, а не только одного. Предлагаем вам сначала определить, как определить кластеризованный индекс так как у вас может быть только один. И прекратите разбрызгивать свой код с помощью nolock.   -  person SMor    schedule 24.03.2021
comment
Для отправленного вами запроса я бы выбрал вариант 1 и порядок столбцов CityId, IsActive и TempDate. В индексах сначала должны быть указаны предикаты равенства. Пища для размышлений - действительно ли вы используете WID в каких-либо запросах?   -  person Dan Guzman    schedule 24.03.2021
comment
Еще два момента: TempF и TempC являются избыточными, укажите один и сделайте другой вычисляемым столбцом. TOP (1000) без ORDER BY является недетерминированным и каждый раз может возвращать разные результаты   -  person Charlieface    schedule 25.03.2021
comment
Спасибо за ввод SMor - Поскольку в этой таблице несколько столбцов, выберите столбцы в основном Cityname, TempF. Для предложения where yes может быть дополнительный фильтр IsDeleted = 0, [TempF] не равно нулю. Вот и все. Но данных было бы очень много, это меня беспокоит.   -  person ASmith    schedule 25.03.2021
comment
Нет, Дэн, WID не используется, спасибо   -  person ASmith    schedule 25.03.2021
comment
Спасибо, Чарлифейс, предложение вычисленного столбца отличное   -  person ASmith    schedule 25.03.2021
comment
Будет ли разница в производительности Вариант A: СОЗДАТЬ КЛАСТЕРНЫЙ ИНДЕКС [IX_WeatherM_1] ON [dbo]. [WeatherM] ([CityId] ASC, [TempDate] ASC, [IsActive] ASC) Вариант B: создать кластерный индекс на WID, а затем добавить некластеризованный индекс в [CityId] ASC, [TempDate] ASC, [IsActive] ASC, будет ли вариант A и вариант B вести себя одинаково?   -  person ASmith    schedule 25.03.2021