Выбор оптимальных индексов для таблицы SQL Server - PullRequest
7 голосов
/ 31 октября 2010

У меня есть таблица SQL Server со следующей структурой:

CREATE TABLE [dbo].[Log](
 [LogID] [bigint] IDENTITY(1,1) NOT NULL,
 [A] [int] NOT NULL,
 [B] [int] NOT NULL,
 [C] [int] NOT NULL,
 [D] [int] NOT NULL,
 [E] [int] NOT NULL,
 [Flag1] [bit] NOT NULL,
 [Flag2] [bit] NOT NULL,
 [Flag3] [bit] NOT NULL,
 [Counter] [int] NOT NULL,
 [Start] [datetime] NOT NULL,
 [End] [datetime] NOT NULL)

Таблица используется для регистрации действий.Столбцы A - E представляют внешние ключи, Flag1 - Flag3 указывают определенные состояния журнала, а столбцы Start и End отмечают начало и конец действия.

В среднем этотаблица обновляется каждые ~ 30 секунд, а обновление выполняет ~ 50 вставок / обновлений.

Пользователь может сделать запрос из пользовательского интерфейса и отфильтровать данные по любому столбцу и всем комбинациям столбцов и типов столбцов.

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

  1. Создайте один «главный» индекс, который будет содержать все эти столбцы
  2. Определите некоторые из наиболее часто используемых комбинаций фильтров, например[A,D,E], [A, Start, End] и т. Д. И создайте для них индексы
  3. Что-то еще ...

Ответы [ 5 ]

11 голосов
/ 01 ноября 2010

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

  1. Создайте один «главный» индекс, который будет содержать все эти столбцы

Это определенно не хорошая идея - если у вас есть индекс на (A, B, C, D, E) и вы ограничиваете свой запрос значениями B и D, этот индекс совершенно бесполезен , Это только полезно

  • если вы запрашиваете все пять столбцов часто
  • комбинациями, такими как (A, B), (A, B, C), (A, B, C, D) часто

В любом другом случае это пустая трата - не используйте это.

  1. Определите некоторые из наиболее часто используемых комбинаций фильтров, например, [A, D, E], [A, Start, End] и т. Д. И создание индексов для них

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

2 голосов
/ 01 ноября 2010

В любой комбинации индексов внутренние ключи не могут быть использованы, если на внешний ключ также нет ссылки. Скажем, у вас есть индекс на (A,B,C,D):

  • WHERE A=@a AND B=@b AND C=@c AND D=@d полностью использует индекс
  • WHERE A=@a может использовать индекс для фильтрации диапазона строк для сканирования. То же самое для WHERE A=@a AND B=@b, WHERE A=@a AND C=@c и т. Д. Любая комбинация, в которой находится самый левый столбец (A) , может использовать индекс.
  • WHERe B=@b не может использовать индекс. Ни WHERE C=@c, WHERE D=@d, ни любая другая комбинация, которая ошибается A. Другими словами, если столбец A не входит в ограничения запроса, индекс будет недоступен.

Это самые основные правила. Добавьте к этому, что условия JOIN могут или не могут рассматриваться как условия WHERE. А для больших результатов непокрытые индексы могут достигнуть переломного момента . И индексы могут удовлетворять не только условиям поиска, они также могут помочь с предложениями ORDER BY. Фактические создаваемые индексы во многом зависят от шаблона запроса, возможностей ввода-вывода, загрузки обновлений и не в последнюю очередь от накладных расходов на управление размером данных (влияние размера файлов и резервных копий). Движок даст вам подсказки о том, какие индексы можно использовать для запросов (функция Отсутствующие индексы ), но движок никоим образом не будет уравновешивать преимущества индекса со стоимостью одного дополнительного индекса (I / O). , обновляет производительность, размер данных). Существуют Руководства по дизайну индексов , которые довольно хороши, но, конечно, вы должны их прочитать. В конечном счете, выбор правильных индексов зависит от множества факторов и соображений, которые невозможно дать ответ на вопросник.

2 голосов
/ 31 октября 2010

Таблицы журналов редко индексируются, поскольку индексация замедляет операторы INSERT, UPDATE и DELETE.

Я бы рекомендовал:

  • загрузить записи в таблицу (временную илифактическое, индексированное) перед фильтрацией
  • с использованием индексированного представления

В основном - если скорость / производительность представляют большую проблему, индексируйте записи в другой форме таблицы, чтобы регистрация не выполняласьвлияние.

1 голос
/ 31 октября 2010

Один из подходов состоит в том, чтобы SQL Server сообщал вам оптимальное использование.Запустите трассировку на несколько минут, пока таблица используется «типично», а затем запустите помощник по настройке ядра СУБД

0 голосов
/ 01 ноября 2010

Я бы поместил индекс в начало (datetime) и все, исходя из предположения, что несколько запросов к журналу будут начальными с момента начала, а большинство - с начальной точки вперед.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...