Скільки індексів баз даних занадто багато?


109

Я працюю над проектом з досить великою базою даних Oracle (хоча моє запитання однаково добре стосується інших баз даних). У нас є веб-інтерфейс, який дозволяє користувачам здійснювати пошук практично по будь-якій можливій комбінації полів.

Щоб зробити цей пошук швидким, ми додаємо індекси до полів та комбінацій полів, за якими, на нашу думку, користувачі зазвичай здійснюватимуть пошук. Однак, оскільки ми не знаємо, як наші клієнти будуть використовувати це програмне забезпечення, важко сказати, які індекси створити.

Космос - це не проблема; у нас є 4 терабайтних RAID-накопичувачів, з яких ми використовуємо лише невелику частку. Однак я переживаю за можливі штрафи за виконання занадто багато індексів. Оскільки ці індекси потрібно оновлювати кожного разу, коли додається, видаляється чи змінюється ряд, я думаю, було б поганою ідеєю мати десятки індексів на одній таблиці.

Отже, скільки індексів вважається занадто багато? 10? 25? 50? Або я повинен просто висвітлювати справді, дійсно поширені та очевидні випадки та ігнорувати все інше?

Відповіді:


87

Це залежить від операцій, які відбуваються на столі.

Якщо є багато SELECT і дуже мало змін, індексуйте все, що вам подобається .... це (потенційно) пришвидшить оператори SELECT.

Якщо таблицю сильно вдаряють ОНОВЛЕННЯ, ВСТАВКИ + ВИДАЛЕННЯ ... це буде дуже повільно з великою кількістю індексів, оскільки їх потрібно змінювати кожного разу, коли відбувається одна з цих операцій.

Сказавши це, ви можете чітко додати безліч безглуздих індексів до таблиці, яка нічого не зробить. Додавання індексів B-Tree до стовпця з двома різними значеннями буде безглуздим, оскільки це не додасть нічого з точки зору пошуку даних. Чим більше унікальних значень у стовпці, тим більше буде користі від індексу.


1
Просто для уточнення, індекс на 2 значення може не бути безглуздим у конкретному випадку, коли одне значення трапляється рідко, і ви хочете його шукати. Тож справа не в тому, наскільки унікальні значення, а в тому, наскільки вибірковий індекс.
charlie_pl

44

Я зазвичай так дію.

  1. Отримайте журнал реальних запитів, що виконуються на даних у типовий день.
  2. Додайте індекси, щоб найбільш важливі запити потрапляли до індексів у їхньому плані виконання.
  3. Постарайтеся уникати індексування полів, які мають багато оновлень або вставок
  4. Після кількох індексів отримайте новий журнал і повторіть.

Як і будь-яка оптимізація, я зупиняюсь, коли досягається запитувана ефективність (це очевидно означає, що точка 0. отримає конкретні вимоги до продуктивності).


26

Всі інші давали вам чудові поради. У мене є додаткова пропозиція для вас, коли ви рухаєтесь вперед. У якийсь момент ви повинні прийняти рішення щодо вашої найкращої стратегії індексації. Зрештою, найкраща ПЛАНОВА стратегія індексування все ще може створити індекси, які не закінчуються звиканням. Одна з стратегій, яка дозволяє знаходити індекси, які не використовуються, - це моніторинг використання індексу. Ви робите це так:

alter index my_index_name monitoring usage;

Потім ви можете відстежувати, чи використовується індекс з цього моменту вперед, запитуючи v $ object_usage. Інформацію про це можна знайти в Посібнику адміністратора бази даних Oracle® .

Просто пам’ятайте, що якщо у вас складена складова стратегія скидання індексів перед оновленням таблиці, а потім їх відтворення, вам доведеться знову встановити індекс для моніторингу, і ви втратите всю історію моніторингу цього індексу.


14

У зберіганні даних дуже часто існує велика кількість індексів. Я працював з таблицями фактів, що мають двісті стовпців і 190 з них індексовано.

Хоча це накладні витрати, це потрібно розуміти в контексті, що в сховищі даних ми зазвичай вставляємо рядок лише один раз, ми ніколи не оновлюємо її, але потім вона може брати участь у тисячах SELECT запитів, які можуть отримати користь від індексації на будь-якому з стовпчики.

Для досягнення максимальної гнучкості сховище даних, як правило, використовує односкладні растрові індекси, за винятком стовпців високої кардинальності, де можна використовувати (стиснуті) btree-індекси.

Накладні витрати на обслуговування індексу здебільшого пов'язані з витратами на запис на велику кількість блоків, і блок розбивається, оскільки нові рядки додаються зі значеннями, що знаходяться "посередині" існуючих діапазонів значень для цього стовпця. Це можна пом'якшити, розділивши і встановивши нове завантаження даних, вирівняне зі схемою розподілу, та використовуючи вставки прямого контуру.

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


Що багато на факт? Я б здогадався, що ти збираєшся сказати розмірність. Це досить химерна справа. Але, ви рок як DBA, так що я скажу, я очевидно чогось не вистачає.
Стефанія Сторінка

@ Стефані, у нас дуже однаковий сценарій .. Девід згадав, що це растрові індекси. Ми також використовуємо індекси BITMAP JOIN. Так, на факти. Oracle може робити дуже ефективні операції AND на растрових індексах. Наприклад, у вас може бути пункт WHERE з 5 атрибутами низької кардинальності, кожен з яких має індекс растрових зображень. Якщо ви подивитесь на план виконання, він би мав растрові карти І операції (в основному це ефективна растрова карта та операція), то внизу плану виконання ви побачите конвертацію растрових зображень у рядки. Це дійсно швидко.
Тагар

12

У парафразі Ейнштейна про простоту додайте стільки індексів, скільки вам потрібно, і не більше.

Однак якщо серйозно, кожен доданий вами індекс вимагає обслуговування, коли дані додаються до таблиці. У таблицях, які в основному читаються лише, багато індексів - це добре. На високодинамічних таблицях краще менше.

Моя порада полягає в висвітленні поширених і очевидних випадків, а потім, коли ви стикаєтеся з проблемами, де вам потрібна більша швидкість отримання даних із конкретних таблиць, оцінюйте та додайте індекси в цей момент.

Крім того, непогано переоцінювати схеми індексації кожні кілька місяців, просто щоб побачити, чи є щось нове, що потребує індексації, або якісь створені вами індекси, які не використовуються ні для чого і чого слід позбутися. .


1
Я погоджуюся на переоцінку. Гарне адміністрування ніколи не є завданням «встановити його і забути». Зміни програмного забезпечення. Вимоги змінюються. Зміни використання. Нова, здавалося б, тривіальна функціональність, запроваджена одного дня, може швидко стати вашим найбільшим вузьким місцем, і вчорашній наріжний код хлібо-вершкового коду може стати спокійним і непотрібним жиром, який просто звисає навколо споживаних ресурсів. Я також згоден з ітераційним підходом. Якщо ви зробите занадто багато одразу, ви не будете знати, що спрацювало.
дуретте

6

На додаток до балів, які всі інші підняли, Оптимізатор на основі витрат несе витрати при створенні плану для оператора SQL, якщо індексів більше, тому що існує більше комбінацій для розгляду. Ви можете зменшити це за допомогою правильних змінних змінних, щоб оператори SQL залишалися в кеші SQL. Потім Oracle може зробити м'який розбір і повторно використовувати план, який він знайшов минулого разу.

Як завжди, нічого простого. Якщо задіяні перекошені стовпці та гістограми, це може бути поганою ідеєю.

У наших веб-додатках ми прагнемо обмежувати комбінації пошуку, які ми дозволяємо. В іншому випадку вам доведеться перевірити буквально кожну комбінацію на продуктивність, щоб переконатися, що у вас не було проблем, що хтось знайде одного дня. Ми також застосували обмеження ресурсів, щоб зупинити це, спричиняючи проблеми в інших місцях програми, якщо щось піде не так.


Я проголосував, але ... я б сказав, що додатковий час розбору, хоча цікавий і академічний, це ніколи не вплине на мій вибір на правильну кількість індексів. згоден?
Стефанія Сторінка

@StephaniePage Я не робив експерименту, щоб щось довести. Однак я бачив проект, який наївно створював одноколонний індекс у кожній колонці. Якщо деякі таблиці містять 80 стовпців, я думаю, це може почати впливати. Oracle, здається, враховує вартість доступу по кожному індексу. Але так, я згоден, є важливіші речі, ніж це.
ВВ.

Ммм ... Я вважаю, що існує максимум часу, який Oracle витратить на жорсткий розбір ... розгляньте SQL з більш ніж декількома таблицями, скажімо, 7 або 8, вибір вибору замовлення приєднатися сам по собі може створити сотні можливих шляхи доступу.
Стефанія Сторінка

6

Я зробив кілька простих тестів на своєму реальному проекті та реальній базі даних MySql. Я вже відповідав у цій темі: Яка вартість індексації кількох колонок db?

Але я думаю, що буде краще, якщо я цитую його тут:

Я зробив кілька простих тестів, використовуючи свій реальний проект та реальну базу даних MySql.

Мої результати: додавання до таблиці середнього індексу (1-3 стовпців в індексі) - робить вставки повільнішими на 2,1%. Отже, якщо ви додасте 20 індексів, ваші вставки будуть повільнішими на 40-50%. Але ваш вибір буде в 10-100 разів швидшим.

То чи добре додавати багато індексів? - Це залежить :) Я дав вам свої результати - Ви вирішуєте!


Це не слід сприймати як пророцтво без усіх деталей. Тим більше, що ви не можете примножувати приріст / втрату продуктивності від однієї дії до іншої. Основа залишається такою ж: додайте більше індексів, і ваші вставки з часом будуть повільнішими через відтворення індексу.
Радянський кордон

3

Зрештою, скільки потрібних вам індексів залежить від поведінки ваших додатків, які працюють на вершині вашого сервера баз даних.

Загалом, чим більше ви вставляєте, тим болючішими стають ваші індекси. Кожен раз, коли ви робите вставку, всі індекси, які містять цю таблицю, повинні оновлюватися.

Тепер, якщо у вашій програмі є достатня кількість читання, або навіть більше, якщо це майже все читання, то індекси - це шлях, оскільки відбудуться значні покращення продуктивності за дуже невеликі витрати.


3

На мій погляд, немає статичної відповіді, така річ підпадає під "настройку продуктивності".

Можливо, все, що робить ваш додаток, шукається первинним ключем, або це може бути суто тим, що запити виконуються над необмеженими комбінаціями полів, а будь-яке зокрема може бути використане в будь-який момент часу.

Крім індексації, існує ваша реогранізація БД для включення розрахованих полів пошуку, розділення таблиць тощо - це дійсно залежить від ваших форм завантаження та параметрів запиту, скільки / які дані 'насправді потрібно повернути запитом.

Якщо весь ваш БД стикається фасадами збереженої процедури, поворот стає трохи простішим, оскільки вам не доведеться турбуватися про кожен спеціальний запит. Або ви можете глибоко розуміти тип запитів, які стосуватимуться вашої БД, і можете обмежити налаштування на них.

Для SQL Server я виявив корисним радника з налаштування двигунів баз даних - ви налаштували "типові" робочі навантаження, і він може давати рекомендації щодо додавання / видалення індексів та статистики. Я впевнений, що інші БД мають подібні інструменти, або "офіційні", або сторонні.


3

Це справді більше теоретичні питання, ніж практичні. Вплив індексів на вашу ефективність залежить від обладнання, яке ви маєте, версії Oracle, типів індексів і т. Д. Вчора я почув, що Oracle оголосив про спеціальне сховище, виготовлене HP, яке повинно працювати в 10 разів швидше з базою даних 11 г. Що стосується вашого випадку, то тут може бути декілька рішень: 1. Майте велику кількість індексів (> 20) та перебудовуйте їх щодня (щоночі). Це буде особливо корисно, якщо таблиця отримує тисячі оновлень / видалень щодня. 2. Розділіть свою таблицю (якщо це стосується вашої моделі даних). 3. Використовуйте окрему таблицю для нових / оновлених даних та запустіть нічний процес, який поєднує дані разом. Це вимагатиме зміни логіки вашої програми. 4. Перейдіть до IOT (таблиця, організована індексом), якщо ваші дані це підтримують.

Звичайно, для такого випадку може бути набагато більше рішень. Першою моєю пропозицією вам було б клонувати БД до середовища розробки та провести проти нього деякі стрес-тести.


Я не розумію, як відновлення індексів допомогло б, або як допоможе IOT.
Девід Олдрідж

IOT - якщо можливо переробити додаток, щоб використовувати новий тип даних, визначений користувачем, то IOT збереже накладні витрати навколо індексації таблиці. це може бути не так. це дійсно залежить. відновлення індексу - якщо індексів багато, а нові дані не індексуються.
Моше

IOT все ще є структурою індексу, з більшою накладною витратою на розбиття блоків, ніж звичайний індекс. "відновлення індексу - якщо індексів багато, а нові дані не індексуються" ... про яку RDBMS ви говорите, яка не підтримує індекси автоматично для нових записів?
Девід Олдрідж

Девід - ти, звичайно, маєш рацію. Я це змішав зі здатністю SQL Server індексувати повний пошук тексту лише за потребою. Wish Oracle мав це, оскільки він може бути корисним у цьому випадку. Я рекомендую дотримуватися двох інших пропозицій.
Моше

2

Якщо ви здебільшого читаєте (і кілька оновлень), то насправді немає причин не індексувати все, що вам потрібно проіндексувати. Якщо ви часто оновлюєтесь, можливо, вам знадобиться бути обережними щодо кількості ваших індексів. Немає жодного важкого числа, але ви помітите, коли все почне сповільнюватися. Переконайтеся, що ваш кластерний індекс є тим, який має найбільш сенс на основі даних.


2

Одне, що ви можете врахувати, - це створення індексів для націлювання на стандартну комбінацію пошукових запитів. Якщо колонку1 часто шукають, і стовпчик2 часто використовується з нею, а стовпець3 іноді використовується з колонкою2 і стовпцем1, то індекс на колонку1, стовпчик2 і стовпець3 у цьому порядку може використовуватися для будь-якого з цих трьох обставин, хоча це лише один індекс, який потрібно підтримувати.


2

Індекс накладає вартість при оновленні базової таблиці. Індекс надає перевагу, коли його використовують для розсипання запиту. Для кожного індексу потрібно збалансувати витрати та вигоди. На скільки повільніше працює запит без індексу? Скільки користі працює швидше? Чи можете ви чи ваші користувачі терпіти малу швидкість, коли індекс відсутній?

Чи можете ви терпіти додатковий час, необхідний для завершення оновлення?

Вам потрібно порівняти витрати та вигоди. Це особливо стосується вашої ситуації. Немає ніякої магічної кількості індексів, яка переступає поріг "занадто багато".

Існує також вартість місця, необхідного для зберігання індексу, але ви сказали, що у вашій ситуації це не проблема. Те саме стосується більшості ситуацій, враховуючи те, наскільки дешевим стало місце на диску.


1

Скільки стовпців є? Мені завжди казали робити одноколонкові індекси, а не багатоколоночні індекси. Тож не більше індексів, ніж кількість стовпців, ІМХО.


1

Що насправді зводиться до цього, не додайте індекс, якщо ви не знаєте (а це часто означає збір статистики використання), що він буде використовуватися набагато частіше, ніж оновлений.

Будь-який індекс, який не відповідає цим критеріям, обійдеться вам більше, ніж збільшити показник продуктивності, якщо не використовувати його у випадковому випадку, до якого він звик.


1

Сервер Sql дає вам кілька хороших інструментів, які дозволяють вам бачити, які індекси використовуються насправді. Ця стаття, http://www.mssqltips.com/tip.asp?tip=1239 , дає вам деякі запити, які дозволяють вам краще зрозуміти, скільки індексу використовується, на відміну від того, наскільки він оновлюється.


0

Він повністю базується на стовпцях, які використовуються у пункті «Де». А як великий палець правила, ми повинні мати індекси на стовпчиках із зовнішніми ключами, щоб уникнути помилок DEADLOCKS. Звіт AWR повинен періодично аналізувати, щоб зрозуміти потребу індексів.


2
Індекси стовпців із зовнішніми ключами, щоб уникнути тупикових ситуацій? Чи є у вас посилання, що пояснює, чому і як це відбувається?
Джей Салліван
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.