Ответы:
Должен ли я начать индексирование с самого начала или когда возникает проблема с производительностью?
Стратегия индексирования имеет тенденцию развиваться по мере появления моделей использования. Тем не менее, есть также стратегии и руководящие принципы проектирования, которые могут быть применены заранее.
Выберите хороший ключ кластеризации . Обычно вы можете определить соответствующий кластеризованный индекс во время разработки на основе ожидаемого шаблона вставок в таблицу. Если появится убедительная причина для изменений в будущем, пусть будет так.
Создайте свои основные и другие уникальные ограничения . Они будут обеспечены уникальными индексами.
Создайте свои внешние ключи и связанные некластеризованные индексы . Внешние ключи - ваши наиболее часто используемые столбцы соединения, поэтому индексируйте их с самого начала.
Создавайте индексы для любых явно высокоселективных запросов . Для шаблонов запросов, которые вы уже знаете, они будут очень избирательными и, скорее всего, будут использовать поиск, а не сканирование.
Помимо вышесказанного, применяйте постепенный и целостный подход к внедрению новых индексов. Под целостным я подразумеваю оценку потенциальной выгоды и воздействия на все запросы и существующие индексы при оценке дополнения.
Не редкая проблема в кругах SQL Server заключается в чрезмерной индексации в результате указаний из отсутствующих указателей DMV и подсказок SSMS. Ни один из этих инструментов не оценивает существующие индексы и будет рад предложить вам создать новый индекс из 6 столбцов, а не добавлять один столбец в существующий индекс из 5 столбцов.
-- If you have this
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable]
(
[col1] ASC
, [col2] ASC
, [col3] ASC
, [col4] ASC
, [col5] ASC
)
-- But your query would benefit from the addition of a column
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable]
(
[col1] ASC
, [col2] ASC
, [col3] ASC
, [col4] ASC
, [col5] ASC
, [col6] ASC
)
-- SSMS will suggest you create this instead
CREATE NONCLUSTERED INDEX [IX_MyTable_AnotherIndexWithTheSameColumnsAsTheExistingIndexPlusCol6] ON [dbo].[MyTable]
(
[col1] ASC
, [col2] ASC
, [col3] ASC
, [col4] ASC
, [col5] ASC
, [col6] ASC
)
Кимберли Трипп (Kimberly Tripp) обладает отличным материалом по стратегии индексирования, который, в то время как сфокусированный на SQL, применим для других платформ. Для разработчиков SQL Server есть несколько удобных инструментов для идентификации дубликатов, как в примере выше.
Мы также можем создать временный индекс при выполнении запроса. Каковы плюсы и минусы таких методов?
Обычно это относится только к редко запускаемым запросам, обычно к ETL. Вам необходимо оценить:
Там действительно риски, связанные с обоими подходами:
Вариант а) Индексируйте с самого начала, но не осознайте, что вы создали ряд индексов, которые никогда не используются. Это добавляет некоторые накладные расходы (наиболее заметно к запросам, которые изменяют данные, но также и с оптимизацией операторов SELECT, пытающихся определить лучший индекс).
Вам нужно будет дисциплинировать себя, чтобы идентифицировать индексы, которые больше не используются, и попытаться удалить их (PostgreSQL может сделать это; к сожалению, MySQL в сравнении очень слаб в этом из коробки).
Вариант б) Не добавляйте индексы до тех пор, пока люди не начнут жаловаться, или ваши диагностические инструменты не приведут к тому, что некоторые запросы будут медленными и могут быть улучшены.
Риск, который вы вводите, заключается в том, что у вас нет достаточно большого временного интервала между моментом, когда вы заметили, что вам нужен индекс, и тем, когда вам нужно его добавить.
PostgreSQL поддерживает создание индексов CONCURRENTLY
, что снижает нагрузку от этого внезапного добавления индекса, но в руководстве есть некоторые оговорки .
Вариант (б) имеет тенденцию быть моим предпочтением, но я думаю, что гибрид обоих вариантов, вероятно, является лучшим решением. Это связано с вашим уровнем уверенности относительно того, считаете ли вы, что индекс действительно будет использоваться.
Что делает это особенно сложным обсуждением, так это то, что обычно легко изменить индексы, но сложнее изменить схему. Я не хочу продвигать отсроченную реакцию b как оправдание безрассудства.
В дополнение к ответу Марка
Вы можете почувствовать, имея реалистичные данные испытаний в ожидаемых количествах. Я видел много, много (слишком много) случаев, когда запрос выполняется нормально с 1000 строками, но не с миллионами в производстве.
Если вы можете, работать над копией производства позже,
Конечно, я видел странную проблему только в производстве из-за моделей использования, когда все остальное идентично
Временные индексы? Вне шаблонов загрузки ETL, если они вам понадобятся один раз, они понадобятся вам снова. Не забывайте: создание / удаление индекса - это запись и запись в журнал = больше нагрузки
Просто чтобы добавить несколько вещей.
Это мой подход.
Не бойтесь ставить > 0
или > ""
в ваших пунктах where неиспользуемые столбцы.
select * from blah
where A="one"
and B="two"
and C>="" --to match index
and D="four"
--This will use your existing index. No need to create a redundant one.
Я постараюсь ответить только на первый вопрос. Если вы с самого начала можете приблизительно оценить, сколько записей будет в ваших таблицах через определенный промежуток времени, то я бы сказал, что лучше начать с самого начала для разработки некоторых индексов. Попробуйте использовать некоторые тестовые инструменты или тестовые сценарии, которые будут автоматизировать как можно больше вызовов для вызовов приложений, которые, по вашему мнению, будут использоваться чаще всего, и вы увидите, каких таблиц можно избежать с самого начала.
Сначала это будет предположение, но со временем, когда у вас будет правильная статистика использования, у вас будет более четкое изображение.