Каково влияние операций CRUD и JOINS с несколькими индексами? - PullRequest
1 голос
/ 07 сентября 2011

У меня есть таблица с 120 столбцами.На нем 8 индексов (1 кластеризованный, 7 некластеризованных).В качестве теста я вставил в таблицу 3400 строк, и это заняло в среднем 12 секунд.

Я создал ту же таблицу с другим именем, создал 32 дополнительных индекса (всего 40 индексов) и снова вставилна те же 3400 строк это заняло в среднем 13,5 секунд.

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

У меня есть 2 вопроса:

1) Правда ли, что для каждого индекса создается копия таблицы?

2) 32 индекса добавляют только 1,5 секунды для одной и той же команды INSERT.Это среднее значение остается для 10000 строк?или для 80 индексов?


У меня есть другой вопрос:

3) когда у нас есть внешний ключ для столбца, SQL Server автоматически создает некластерный индекс для него . Когда у нас есть передний ключ для столбца Если мы создаем некластерный индекс для него, полезен ли этот индекс для запросов или объединений?

Ответы [ 3 ]

3 голосов
/ 07 сентября 2011

1) op спрашивает: Is it true that by every index a copy of table created? это не так.Индекс будет хранить индексированные столбцы и указатель обратно (например, кластеризованный PK и т. д.) на строку.он также будет хранить любые столбцы INCLUDE, но это уже другая тема.

2) Трудно угадать время, не зная аппаратное обеспечение, таблицы или индексы, о которых идет речь.Я уверен, что SQL Server хорош в оптимизации обслуживания индексов.Вы должны проверить это, вставив те же строки только с PK, а затем повторить попытку с 40 индексами, а затем снова с 80. Я уверен, что большую часть времени составляют только вставки.

EDIT

3) op спрашивает when we have a Foreign key on a column SQL Server automatically create non-cluster index on it.this Index useful for quering or Joins? SQL Server НЕ создает автоматически индекс для внешних ключей.Однако добавление индекса по столбцам FK может быть полезным.Если вы напишите запрос, объединяющий две таблицы в FK, тогда индекс МОЖЕТ использоваться.Рассмотрим следующее:

tableA
RowID    int PK
RowDate  datetime
OtherID  int

tableB
OtherID  int PK
someValue varchar(5)

, если вы добавляете FK для tableA.OtherID в tbaleB.OtherID и используете этот запрос:

select * from tableA a INNER JOIN tableB b ON a.OtherID=b.OtherID
WHERE a.RowDate<'2011/1/1'

, тогда индекс для tableA.OtherID не будетбудет использоваться индекс для tableA.RowDate и будет использоваться индекс PK для tableB.OtherID.

select * from tableA a INNER JOIN tableB b ON a.OtherID=b.OtherID 
WHERE b.someValue='AA'

could also be written as:

select * from tableb b INNER JOIN tableA b ON b.OtherID=a.OtherID 
WHERE b.someValue='AA'

, затем можно использовать индекс для tableA.OtherID и любой индекс для tableb.Будет использовано someValue.

2 голосов
/ 07 сентября 2011

1) Верно ли, что для каждого индекса создается копия таблицы?

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

2) 32 индекса добавляют только 1,5 секунды для одной и той же команды INSERT. Является ли это средние остаются на 10 000 строк? или для 80 индексов?

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

1 голос
/ 07 сентября 2011

1) Правда ли, что для каждого индекса создается копия таблицы?

Частично. Столбцы, которые индексируются определенным (некластеризованным) индексом, будут «скопированы» в структуру данных индекса (обычно это B-дерево), а остальные столбцы - нет. Кстати, некоторые RDMBS поддерживают форму сжатия индексов (например, Oracle, не уверенный в MS SQL Server), которая может значительно «уменьшить» след индекса низкой селективности.

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

Однако , кластеризованный индекс увеличивает «копирование», которое происходит для всех других (т.е. некластеризованных) индексов. Из MSDN:

"Значения ключей из кластеризованного индекса используются всеми некластеризованными индексами в качестве ключей поиска и, следовательно, хранятся в каждой записи листа некластеризованного индекса."

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

2) 32 индекса добавляют только 1,5 секунды для той же команды INSERT. Это среднее значение остается для 10000 строк? или для 80 индексов?

Имея только 3400 строк (или 10 000 в этом отношении), я подозреваю, что вы все еще находитесь в пределах кеша, что может скрыть проблему производительности, которую вы, вероятно, будете иметь, поддерживая все эти индексы для большего набора данных. Как всегда, вы не будете знать наверняка, пока не сравнитесь с репрезентативными объемами данных ...

--- РЕДАКТИРОВАТЬ ---

3) когда у нас есть внешний ключ в столбце, SQL Server автоматически создает некластерный индекс для него. Этот индекс полезен для запросов или объединений?

Может увеличивать или не увеличивать производительность в зависимости от того, как составлен конкретный запрос. Это также может быть важно для каскадной ссылочной целостности (ON DELETE / UPDATE CASCADE).

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

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