Подтвердить что ты не робот

Как определить, когда использовать индекс в столбце таблицы

Когда следует использовать индекс в таблице?

  • Сколько строк имеет смысл?
  • Если у меня есть таблица с постоянными строками, только отредактированные столбцы ввода (не в разделе "where" ), имеет смысл индекса, даже если таблица имеет всего около 15 строк? EDIT: Может ли быть в таком случае выбор/чтение неиндекса более эффективным, чем индекс?

EDIT: Теперь я работаю с firebird 2.5, но большую часть времени я использую SQL Server 2005/2008.

4b9b3361

Ответ 1

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

  • выберите хороший ключ кластеризации - не GUID, а не VARCHAR(250) или что-то - хороший ключ кластеризации является узким, уникальным, стабильным, когда-либо -увеличение - что-то вроде INT IDENTITY идеально. Делает этот кластерный первичный ключ → дает вам свой первый индекс в таблице

  • для любого столбца, который используется в качестве внешнего ключа в другой таблице - добавьте индекс. Это может быть либо один индекс столбца, либо он может быть составным индексом - что лучше всего подходит для вашего дела. Важно, чтобы столбец внешнего ключа был столбцом first в этом индексе (если вы используете составной индекс) - в противном случае преимущества для JOIN или для проверки ссылочной целостности не будут доступный вашей системе

И это на данный момент.

Затем: запустите свою систему - наблюдайте и измерьте - установите базовую линию. Является ли приложение достаточно быстрым? Если да → вы закончили - идите домой и наслаждайтесь свободным временем.

Если нет: тогда начните собирать данные и указания относительно того, почему приложение не достаточно быстро. Посмотрите, например. такие как DMV в SQL Server, которые рассказывают вам о наихудших исполняемых запросах или недостающем индексе DMV. Проанализируйте их. Посмотрите, что вы можете улучшить. Добавьте по одному индексу за раз и снова: наблюдайте, измерьте, сравните с базовым уровнем.

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

Переиндексация в SQL Server может быть хуже, чем отсутствие индексов. Не начинайте со слишком большого количества индексов для начала! Создайте только хорошие кластерные PK и некластеризованные индексы внешнего ключа - все - тогда наблюдайте, измеряйте, оптимизируйте и повторяйте этот цикл.

Ответ 2

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

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

Если вы используете SQL Server, вы можете запустить трассировку с помощью профилировщика SQL Server, чтобы помочь вам

EDIT:

Может быть в таком случае неиндексный выбор/чтение более эффективным, чем индекс читается?

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

Ответ 3

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

Некоторые из них упомянули о базовом уровне, используя какую-то утилиту трассировки для измерения производительности и т.д. Если вы в порядке с установленной производительностью, переходите. Если нет, проанализируйте план выполнения, модель физических данных (доступные индексы), перечислите статистику и посмотрите, помогает ли оптимизатор выбрать лучший план выполнения. Убедитесь, что СУБД может (разрешено) использовать доступную оперативную память. Постарайтесь минимизировать дисковый ввод-вывод и т.д.

В случае Firebird 2.5 недавно добавленный API трассировки Firebird является находкой. Теперь вы, наконец, можете получить почти реальную трассировку на то, что выполнено против базы данных с счетчиками производительности (план выполнения, время выполнения, статистика ввода-вывода...). И сторонний продукт под названием FB TraceManager от Upscene Productions делает Trace API радостью для использования.

Ответ 4

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

Ответ 5

Я использую этот запрос для получения подсказки о том, какая из моих таблиц нуждается в индексе:

-- Missing Indexes for current database by Index Advantage  (Query 57) (Missing Indexes)
SELECT DISTINCT CONVERT(decimal(18,2), user_seeks * avg_total_user_cost * (avg_user_impact * 0.01)) AS [index_advantage], 
migs.last_user_seek, mid.[statement] AS [Database.Schema.Table],
mid.equality_columns, mid.inequality_columns, mid.included_columns,
migs.unique_compiles, migs.user_seeks, migs.avg_total_user_cost, migs.avg_user_impact,
OBJECT_NAME(mid.[object_id]) AS [Table Name], p.rows AS [Table Rows]
FROM sys.dm_db_missing_index_group_stats AS migs WITH (NOLOCK)
INNER JOIN sys.dm_db_missing_index_groups AS mig WITH (NOLOCK)
ON migs.group_handle = mig.index_group_handle
INNER JOIN sys.dm_db_missing_index_details AS mid WITH (NOLOCK)
ON mig.index_handle = mid.index_handle
INNER JOIN sys.partitions AS p WITH (NOLOCK)
ON p.[object_id] = mid.[object_id]
WHERE mid.database_id = DB_ID() 
ORDER BY index_advantage DESC OPTION (RECOMPILE);

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