Відповіді:
Чи варто починати індексувати з самого початку або коли виникає проблема з продуктивністю?
Стратегія індексування, як правило, розвивається в міру появи моделей використання. З огляду на це, існують також стратегії та рекомендації щодо проектування, які можна застосувати наперед.
Виберіть хороший кластерний ключ . Зазвичай можна визначити відповідний кластерний індекс під час проектування, виходячи з очікуваного шаблону вставок до таблиці. Якщо переконливий випадок для зміни в майбутньому, так і нехай буде.
Створіть свої основні та інші унікальні обмеження . Вони виконуватимуться за допомогою унікальних індексів.
Створіть свої зовнішні ключі та пов’язані з ними некластеризовані індекси . Іноземні ключі - це ваші найпоширеніші стовпчики приєднання, тому індексуйте їх із самого початку.
Створіть індекси для будь-яких очевидно високоселективних запитів . Для моделей запитів, які ви вже знаєте, вони будуть вкрай вибірковими і, скоріш за все, використовуватимуть пошук, а не сканування.
Крім вищесказаного, використовуйте поступовий і цілісний підхід до впровадження нових індексів. Під цілісним я маю на увазі оцінку потенційної вигоди та впливу на всі запити та існуючі індекси при оцінці додавання.
Нечастою проблемою в колах 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. Вам потрібно оцінити:
Існують реальні ризики, пов'язані з обома підходами:
Варіант a) Індекс з самого початку, але не розуміючи, що ви створили ряд індексів, які ніколи не використовуються. Вони додають деякі накладні витрати (найбільш помітно до запитів, що змінюють дані, але також з оптимізацією операторів SELECT, що намагаються визначити найкращий індекс).
Вам потрібно буде дисциплінувати себе, щоб виявити індекси, які більше не використовуються, і спробувати їх видалити (PostgreSQL може це зробити; на жаль, MySQL порівняно дуже слабкий у цьому з поля).
Варіант b) Не додайте покажчики, поки люди не почнуть скаржитися, або якщо ваші діагностичні засоби не спричинить, що певні запити повільні та їх можна вдосконалити.
Ризик, який ви вводите, полягає в тому, що у вас немає достатньо великого часового вікна між тим, коли ви помітите, що вам потрібен індекс, і коли вам доведеться його додати.
PostgreSQL підтримує індекси побудови CONCURRENTLY
, що дозволяє зменшити деякий стрес від цієї необхідності раптового додавання до індексу, але є деякі застереження, зазначені в посібнику.
Варіант (b), як правило, є моїм уподобанням, але я думаю, гібрид обох варіантів, мабуть, найкраще рішення. Це стосується вашого рівня довіри щодо того, чи вважаєте ви, що індекс буде використаний насправді.
Що робить це особливо складним обговоренням, це те, що зазвичай змінювати індекси легко, але змінити схему складніше. Я не хочу пропагувати затримку реакції b як привід бути необачним.
Окрім відповіді Марка
Ви можете відчути, отримавши реальні дані тесту в очікуваних кількостях. Я бачив багато, багато (занадто багато) випадків, коли запит працює в порядку з 1000 рядками, але не мільйон у виробництві.
Якщо ви можете, працюйте над копією продукції пізніше,
Звичайно, дивну проблему я бачив лише у виробництві через схеми використання, коли все інше тотожне
Тимчасові індекси? Поза моделями завантаження ETL, якщо вони вам знадобляться, вам вони знадобляться знову. Не забувайте: створення / падіння індексу - це запис і реєструється = більше завантаження
Просто додати кілька речей.
Це мій підхід.
Не бійтеся поміщати > 0
або вказувати > ""
свої пропозиції про невикористані стовпці.
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.
Я спробую відповісти лише на перше запитання. Якщо ви можете з початку оцінити навіть приблизно, скільки записів у вас буде за таблицями через певний проміжок часу, ніж я б сказав, що краще почати спочатку розробляти деякі індекси. Спробуйте скористатися деякими тестовими інструментами або тестовими сценаріями, які дозволять автоматизувати якомога більше дзвінків для дзвінків додатків, які, на вашу думку, найчастіше використовуються, і ви побачите, яких сканувань таблиць можна уникнути з самого початку.
Це буде здогадкою на початку, але з часом, коли ви маєте належну статистику використання, ви матимете чіткіше зображення.