Как ускорить текущий запрос с индексом

Я использую сервер v12 в базе данных Azure SQL, и у меня есть следующая таблица:

CREATE TABLE [dbo].[AudienceNiches]( [Id] [bigint] IDENTITY(1,1) NOT NULL, [WebsiteId] [nvarchar](128) NOT NULL, [VisitorId] [nvarchar](128) NOT NULL, [VisitDate] [datetime] NOT NULL, [Interest] [nvarchar](50) NULL, [Gender] [float] NULL, [AgeFrom18To24] [float] NULL, [AgeFrom25To34] [float] NULL, [AgeFrom45To54] [float] NULL, [AgeFrom55To64] [float] NULL, [AgeFrom65Plus] [float] NULL, [AgeFrom35To44] [float] NULL, CONSTRAINT [PK_AudienceNiches] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) )

Я выполняю этот запрос: (ОБНОВЛЕННЫЙ ЗАПРОС)

 `select a.interest, count(interest) from ( select visitorid, interest from audienceNiches WHERE WebsiteId = @websiteid AND VisitDate >= @startdate AND VisitDate <= @enddate group by visitorid, interest) as a group by a.interest` 

И у меня есть следующие индексы (все ASC):

idx_WebsiteId_VisitDate_VisitorId idx_WebsiteId_VisitDate idx_VisitorId idx_Interest

Проблема в том, что мой запрос возвращает строки 18K aproximaly и занимает 5 секунд, вся таблица имеет записи 8.8M, и если я немного расширю данные, время будет увеличиваться, так что будет лучшим индексом для этого запроса? Что мне не хватает?

Лучшим индексом для этого запроса является составной индекс в этих столбцах в следующем порядке:

  • WebsiteId
  • VisitDate
  • Интерес
  • VisitorId

Это позволяет полностью ответить на запрос из индекса. SqlServer может варьировать сканирование на ( WebsiteId , VisitDate ), а затем исключать нулевой Interest и, наконец, подсчитывать различные VisitorIds все из индекса. Записи индексов будут в правильном порядке, чтобы эти операции могли выполняться эффективно.

Мне трудно писать SQL, не имея данных для тестирования, но посмотрите, дает ли это результаты, которые вы ищете, с лучшим временем выполнения.

 SELECT interest, count(distinct visitorid) FROM audienceNiches WHERE WebsiteId = @websiteid AND VisitDate between @startdate and @enddate AND interest is not null GROUP BY interest 

Индексы могут потребовать почти бесконечного понимания, но в вашем случае я думаю, что вы увидите хорошие показатели производительности, индексируя SiteId и VisitDate как отдельные индексы.

Важно, чтобы убедиться, что ваши индексы в хорошей форме. Вы должны поддерживать их, сохраняя статистику в актуальном состоянии и периодически перестраивая свои индексы.

Наконец, вы должны изучить план запроса при настройке производительности запроса. SQL Server сообщит вам, думает ли он, что это будет полезно для индексирования столбца (или столбцов), а также предупредит вас о других проблемах, связанных с производительностью.

Нажмите Ctrl + L из Management Studio и посмотрите, что происходит с запросом.

Ваш запрос может быть написан таким образом, потому что в окончательном наборе результатов вы не выталкиваете столбец посетителя из таблицы аудиторийNiches, поэтому не нужно писать два разных уровня группы. Проконсультируйтесь с этим вопросом и сообщите мне, если вы все еще сталкиваетесь с проблемой производительности.

 select interest, count(interest) from audienceNiches WHERE WebsiteId = @websiteid AND VisitDate >= @startdate AND VisitDate <= @enddate group by interest 

Во-первых, ваш обновленный запрос может быть эффективно сведен к этому:

 select an.Interest, count(an.Interest) from dbo.AudienceNiches an where an.WebsiteId = @WebSiteId and an.VisitDate between @startdate and @enddate group by an.Interest; 

Во-вторых, в зависимости от мощности ваших данных один из следующих индексов обеспечит наилучшую производительность:

 create index IX_AudienceNiches_WebSiteId_VisitDate_Interest on dbo.AudienceNiches (WebSiteId, VisitDate, Interest); 

или

 create index IX_AudienceNiches_VisitDate_WebSiteId_Interest on dbo.AudienceNiches (VisitDate, WebSiteId, Interest); 

Однако, по мере роста ваших данных, я думаю, что в конечном итоге последний станет более эффективным, в среднем.

PS Ваш стол сильно денормализован в нескольких аспектах. Я надеюсь, что вы знаете, что делаете.

  • Рекомендации по составному индексу
  • Как использовать переменную для указания файловой группы в SQL Server
  • Тайм-аут INSERT во время онлайн-перестройки индекса
  • Является ли хорошей идеей индексировать каждый столбец, если пользователи могут фильтровать любой столбец.
  • Почему создание этого нового индекса значительно повысило производительность, когда существующий индекс включал все столбцы в новый индекс?
  • Кластерный индекс столбца SQL Server в индексированном виде
  • Вставляет / обновляет / удаляет индексы автоматического обновления записей?
  • SQL Server: изменение файловой группы индекса (который также является PK)
  • Производительность индекса SQL
  • Каков эффект включения столбца «include» в некластеризованный индекс, который уже является частью ключа кластеризации?
  • включены столбцы для некластеризованного индекса
  • Давайте будем гением компьютера.