У меня есть одна таблица с десятью внешними ключами. Какую долю попадания я получу при вставке, если у меня есть индексы на все десять ключей? - PullRequest
1 голос
/ 23 июня 2009

Похоже, что все внешние ключи должны иметь индексы. Сколько накладных расходов я буду нести на вкладышах, если буду следовать букве закона?

ПРИМЕЧАНИЯ:

  1. Предположим, что база данных - это хороший дизайн, и что все объединения законны.
  2. Все первичные и внешние ключи имеют тип Int.
  3. Некоторые таблицы - это таблицы поиска, содержащие менее десяти записей, размер которых вряд ли увеличится.
  4. Это база данных OLTP.
  5. Некоторые из соединений предназначены для поиска таблиц, содержащих менее 10 записей.

Ответы [ 10 ]

2 голосов
/ 23 июня 2009

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

Каждая запись в таблицу и в индекс также приведет к трафику журнала. Особенно пагубное наказание накладывается на объемные вставленные данные, так как активные индексы для таблиц, в которые вы вставляете объемные загруженные данные, будут обновляться для каждой строки - и эти обновления не минимально регистрируется. Это значительно унесет ваш ввод-вывод (который будет представлять собой произвольный доступ, а не последовательные массовые записи), а также будет генерировать огромные объемы журнального трафика.

2 голосов
/ 23 июня 2009

Здесь - хороший список примеров того, когда и какой тип индекса использовать. Я не думаю, что вы должны принять «закон» и индексировать все. Вам необходимо определить, что будет использоваться в объединениях запросов и соответствующим образом индексировать

1 голос
/ 23 июня 2009

Вставить / обновить / удалить всегда попадает в индекс и записывает в него. Выберите , иногда попадает в индекс для чтения из него, в зависимости от анализа оптимизатора запросов или наилучшего предположения. Если вам не нужен индекс для ускорения чтения (например, если в столбце только небольшое количество потенциальных значений), избавьтесь от него.

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

1 голос
/ 23 июня 2009

Единственный способ узнать влияние - это проверить. Ответ может сильно отличаться в зависимости от того, имеет ли ваша система тенденцию вставлять большие объемы данных в массовую вставку или по одной записи за раз из пользовательского интерфейса. Это также во многом зависит от размера таблиц и общего количества индексов. Тестирование - это единственный способ точно определить, какие индексы следует использовать. Общее правило - начать с индексации полей внешнего ключа и полей, которые вы будете использовать в предложениях where. Но это именно то, с чего стоит начать смотреть на свою систему, а не ответ «будь все - конец всему».

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

В новой системе вам нужно генерировать тестовые записи в ожидаемом объеме, который будет иметь система при внедрении. Если вы этого не сделаете, то обнаружите, что запросы (и дизайн), которые работали нормально на одном и том же тестовом стенде, могут быть ужасными, так как реальные пользователи одновременно выполняют несколько операций с большими таблицами. Совсем не интересно реорганизовать базу данных, в которой производительность не учитывалась и не проверялась в проекте. Нелегко откатывать производственные изменения, потому что запрос занимает больше времени, чем настройка тайм-аута, потому что разработчик не проверял истинный объем (или новый проект - ожидаемый объем).

В SQL Server есть инструменты, которые помогут вам определить лучшие индексы. Используйте мастер индексирования и планы выполнения, чтобы увидеть, где вам нужны индексы. Поместите индексы в поля и тестовые вставки, чтобы увидеть, есть ли негативное влияние. Там нет ни одного правильного ответа. По всей вероятности, он даже не останется таким же ответом на протяжении всей жизни вашей базы данных.

1 голос
/ 23 июня 2009

Похоже, что все внешние ключи должны иметь индексы. Сколько накладных расходов я буду нести на вкладышах, если буду следовать букве закона?

Существует две накладные расходы: на DML над ссылочной таблицей и DML над ссылочной таблицей.

Ссылочная таблица должна иметь индекс, иначе вы не сможете создать FOREIGN KEY.

Таблица ссылок не может иметь индекса. Это сделает INSERT в ссылочной таблице немного медленнее, и не повлияет на INSERT в ссылочной таблице.

Каждый раз, когда вы вставляете строку в таблицу ссылок, происходит следующее:

  1. Строка проверяется по FOREIGN KEY, как в этом запросе:

    SELECT  TOP 1 NULL
    FROM    referenced ed
    WHERE   ed.pk = @new_fk_value
    
    • строка вставлена ​​
    • Индекс в строке (если есть) обновляется.

Первые два шага всегда выполняются, и шаг 1 обычно использует индекс для ссылочной таблицы (опять же, вы просто не можете создать отношение FOREIGN KEY без этого индекса).

Шаг 1 является единственной служебной информацией, специфичной для FOREIGN KEY.

Накладные расходы шага 3 подразумеваются только тем фактом, что индекс существует. Это было бы точно так же там не было FOREIGN KEY.

Но UPDATE и DELETE из ссылочной таблицы могут быть намного медленнее, если вы не определите индекс в ссылочной таблице, особенно если последняя велика.

Всякий раз, когда вы DELETE из указанной таблицы, происходит следующее:

  1. Строки проверяются по FOREIGN KEY, как в этом запросе:

    SELECT  TOP 1 NULL
    FROM    referencing ing
    WHERE   ing.fk = @old_pk_value
    
    • Строка удалена
    • Индекс в строке обновлен.

Легко видеть, что этот запрос, скорее всего, получит выгоду от индекса на referencing.fk.

В противном случае оптимизатору потребуется построить HASH TABLE по всей таблице, даже если вы удаляете одну запись для проверки ограничения.

1 голос
/ 23 июня 2009

Единственный возможный способ ответить на ваш вопрос - это проверить. Например, если количество ключей равно 10, они, вероятно, не будут очень полезны. Итак, у вас есть работа для тестирования. Но это во многом связано с размерами ваших таблиц, размерами ключей, абсолютным уровнем активности и сочетанием элементов CRUD. Не доверяй всем простым ответам.

EDIT:

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

1 голос
/ 23 июня 2009

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

0 голосов
/ 23 июня 2009

Я знаю, что производительность является критической проблемой.

IMO, вы должны учитывать последствия отсутствия индекса (и, следовательно, отсутствия FK) для данных OLTP. В такой системе могут возникнуть проблемы с целостностью данных.

0 голосов
/ 23 июня 2009

Спасибо всем за ваш вклад.

Судя по вашим отзывам, я добавлю индексы ко всем внешним ключам, КРОМЕ тех, которые указывают на таблицы поиска (содержащие небольшое количество записей, которые вряд ли изменятся). Это сократит количество необходимых индексов внешних ключей в два раза (с десяти до пяти).

Если у кого-то есть дальнейшее понимание, не стесняйтесь отправлять новые ответы. У меня еще осталось несколько голосов. :)

0 голосов
/ 23 июня 2009

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

Редактировать : Таблица просмотра, вероятно, будет кэширована, но это не поможет поисковому запросу в отношении таблицы ссылок. Ваша таблица данных, которая есть.

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