Почему я не могу просто добавить индекс, который включает все столбцы?
У меня есть таблица в базе данных SQL Server, с которой я хочу как можно быстрее искать и извлекать данные. Мне не важно, сколько времени требуется для вставки в таблицу, меня интересует только скорость, с которой я могу получить данные.
Проблема заключается в доступе к таблице с 20 или более разными типами запросов. Это делает утомительную задачу для добавления индекса, специально разработанного для каждого запроса. Я рассматриваю вместо этого просто добавление индекса, который включает ВСЕ столбцы таблицы. Это не то, что вы обычно делаете в "хорошем" дизайне базы данных, поэтому я предполагаю, что есть веская причина, почему я не должен этого делать.
Может ли кто-нибудь сказать мне, почему я не должен этого делать?
ОБНОВЛЕНИЕ: Я забыл упомянуть, я также не забочусь о размере моей базы данных. Это нормально, что это означает, что размер моей базы данных будет больше, чем нужно
Ответы
Ответ 1
Прежде всего, индекс в SQL Server может содержать не более 900 байт в своей записи индекса. Это само по себе делает невозможным наличие индекса со всеми столбцами.
Больше всего: такой индекс не имеет никакого смысла. Чего вы пытаетесь достичь?
Рассмотрим это: если у вас есть индекс на (LastName, FirstName, Street, City)
, этот индекс будет не использоваться для ускорения запросов на
Этот индекс будет полезен для поиска по
-
(LastName)
, или
-
(LastName, FirstName)
, или
-
(LastName, FirstName, Street)
, или
-
(LastName, FirstName, Street, City)
но на самом деле ничего другого - конечно, если вы ищете только Street
или просто City
!
Порядок столбцов в вашем индексе имеет большое значение, и оптимизатор запросов не может просто использовать какой-либо столбец где-то посередине индекса для поиска.
Рассмотрите свою телефонную книгу: она, вероятно, может быть отправлена по LastName, FirstName, может быть, на Street. Так что эта индексация поможет вам найти все "Джо" в вашем городе? Все люди, живущие на "Мейн-стрит"? Нет - вы можете сначала искать LastName - тогда вы получите более конкретную информацию внутри этого набора данных. Просто наличие индекса по всему не ускоряет поиск всех столбцов вообще.
Если вы хотите иметь возможность искать по Street
- вам нужно добавить отдельный индекс на (Street)
(и, возможно, другой столбец или два, которые имеют смысл).
Если вы хотите иметь возможность искать по Occupation
или что-то еще - для этого вам нужен другой конкретный индекс.
Просто потому, что ваш столбец существует в индексе, не означает, что ускорит все поиски этого столбца!
Главное правило: использовать как можно меньше индексов - слишком много индексов может быть еще хуже для системы, чем вообще не иметь индексов... стройте свою систему, контролируйте ее производительность и находите те запросы, которые стоят большинство - затем оптимизируйте их, например путем добавления индексов.
Не просто слепо индексировать каждый столбец только потому, что вы можете - это гарантия застойной производительности системы. Любой индекс также требует обслуживания и поддержки, поэтому чем больше индексов у вас есть, тем больше операций INSERT, UPDATE и DELETE страдают (замедляются), так как все эти индексы необходимо обновить.
Ответ 2
У вас есть фундаментальное непонимание того, как работают индексы.
Прочтите это объяснение " как работают многоколонные индексы.
Следующий вопрос, который у вас может возникнуть, - это почему бы не создать один индекс за столбец - но это тоже тупик, если вы попытаетесь достичь верхний выбор производительности.
Вы можете почувствовать, что это утомительная задача, но я бы сказал, что это требуемая задача для тщательного индексации. Неверное индексирование удаляется, как в в этом примере.
Примечание. Я убежден, что правильное индексирование окупается, и я знаю, что у многих людей есть те же самые вопросы, которые у вас есть. Вот почему я пишу бесплатную книгу об этом. Ссылки, приведенные выше, ссылаются на страницы, которые могут помочь вам ответить на ваш вопрос. Однако вы также можете прочитать его из .
Ответ 3
Я рассматриваю вместо этого просто добавление индекса, который включает ВСЕ столбцы таблицы.
Это всегда плохая идея. Индексы в базе данных - это не какая-то пыль пикси, которая работает магически. Вы должны анализировать свои запросы и в соответствии с тем, что и как запрашивается - добавлять индексы.
Это не так просто, как "добавить все, чтобы индексировать и иметь сон"
Ответ 4
... если вы добавите индекс, содержащий все столбцы, и запрос действительно сможет использовать этот индекс, он будет сканировать его в порядке первичного ключа. Это означает, что вы попадаете почти на каждую запись. Среднее время поиска будет O (n/2).. то же, что и для фактической базы данных.
Вам нужно прочитать фрагмент bit об индексах.
Это может помочь, если вы считаете индекс в таблице немного похожим на словарь в С#.
var nameIndex = new Dictionary<String, List<int>>();
Это означает, что столбец имен проиндексирован и вернет список первичных ключей.
var nameOccupationIndex = new Dictionary<String, List<Dictionary<String, List<int>>>>();
Это означает, что столбцы имен + столбцы заполнения индексируются. Теперь представьте, что индекс содержал 10 разных столбцов, вложенных до сих пор в глубину, он содержит каждую строку в вашей таблице.
Это не совсем то, как он работает на вас. Но это должно дать вам представление о том, как индексы могут работать, если они реализованы в С#. Что вам нужно сделать, это создать индексы на основе одного или двух ключей, которые запрашиваются широко, так что индекс более полезен, чем сканирование всей таблицы.
Ответ 5
Если это операция типа хранилища данных, где запросы очень оптимизированы для запросов READ, и если у вас есть 20 способов анализа данных, например
Предложение WHERE включает в себя..
Q1: status, type, customer
Q2: price, customer, band
Q3: sale_month, band, type, status
Q4: customer
etc
И у вас абсолютно много свободного места для записи, а затем создайте индекс для КАЖДОГО одного столбца, отдельно. Таким образом, таблица из 20 столбцов будет содержать 20 индексов, по одному для каждого отдельного столбца. Я мог бы, вероятно, сказать, чтобы игнорировать столбцы бит или столбцы с низкой мощностью, но поскольку мы зашли так далеко, зачем беспокоиться (с этим предупреждением). Они будут просто сидеть и сбрасывать время WRITE, но если вам не нужна эта часть картины, тогда мы все хорошо.
Проанализируйте свои 20 запросов, и если у вас есть горячие запросы (самые горячие), которые по-прежнему не будут выполняться быстрее, планируйте его с помощью SSMS (нажмите Ctrl-L) с одним запросом в окне запроса. Он расскажет вам, какой индекс может помочь этим запросам - просто создайте его; создайте их все, полностью помня, что это снова добавляет стоимость записи, размер файла резервной копии, время обслуживания db и т.д.
Ответ 6
1), индекс по существу создает копию данных в этом столбце, какую-то структуру с легкостью поиска, такую как двоичное дерево (я не знаю спецификаций SQL Server).
2) Вы упомянули скорость, структуры индексов медленнее добавить.
Ответ 7
Этот индекс будет просто идентичен вашей таблице (возможно, отсортирован в другом порядке).
Это не ускорит ваши запросы.