Чи передчасна оптимізація додавання індексів баз даних?


61

Сьогодні моя колега запропонувала нам пройти всі запити у нашій програмі та відповідно додати індекси.

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

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


32
Це може бути питанням думки, проте я вважаю, що деякі показники можна додавати апріорі.
Базиль Старинкевич

2
@BasileStarynkevitch Повністю погоджуємось з тим, що у нас вже є індекси первинного ключа та роботи. Але де ви проводите лінію?
Марко де Йонг

1
Мої два центи від досвіду: я тестував деякі мої ранні пошукові запити на підмножині нашої бази даних. Тести, які я проводив, були абсолютно відмінними на моїй місцевій копії. Потім я натиснув додаток на область постановки, де розміщується повна база даних. Мої тести тривали <500 мс , тоді як система постановки потребувала декількох хвилин . Мій бос був ретельно розгублений, чому програма не завантажується. Поясніть операції типу вашого друга ... Принаймні шукайте послідовних сканувань на великих столах, як мінімум!
Chris Cirefice

2
Не додавання індексів - це як використання бульбашки. Найчастіше ви не знайдете жодних проблем, коли тестуєте його, але як тільки ваша програма почне масштабування в прямому ефірі, у вас виникає маса проблем. І показники можуть легко зробити коефіцієнт 100 у різниці швидкостей.
Пітер Б

3
Просто пам’ятайте: Індекс - це не чарівна річ, яка прискорить ваші запити. Індекс призведе до витрат на більшість DML-операцій, і залежно від типу може призвести до багато очікування, коли багато людей оновлюють ту саму таблицю. Що стосується запитів: Є багато запитів, які зовсім не виграють від індексу, де FTS є найшвидшим або де розділення виконує всю роботу за вас. - Додавайте лише індекс там, де ви ЗНАЄте, вони будуть корисними!
Фалько

Відповіді:


132

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

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


11
Так, це слід зробити на етапі тестування навантаження
Альваро

152
Оптимізація, перш ніж знати, де знаходяться повільні частини, - це передчасна оптимізація. Звільнити річ, перш ніж знати, де знаходяться повільні частини, передчасне звільнення !
MathematicalOrchid

4
@MathematicalOrchid: Це чудова фраза! Чи можу я позичити його в іншому місці?
Пітер Геркенс

3
@PieterGeerkens Впевнений, вибити себе! ;-) Мені просто сумно, що 91+ грошей не заробляють мені жодної репутації ... хе.
MathematicalOrchid

3
@MathematicalOrchid повинна була відповісти. Не міг працювати за "найменший-прямо-в-точку" відповідь ніколи.
Mindwin

48

слідкуйте за повільними запитами, як тільки ми переходимо в реальність

тому що нічого не говорить про якість, як спонукання ваших користувачів страждати через брак дизайну!

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


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

1
@DocBrown Я не дуже впевнений, коли ви розробляєте таблицю, ви маєте (або повинні мати) розуміння того, як її використовувати. Таблиця особи буде запитуватися за ідентифікатором або, можливо, прізвищем. Якщо хтось починає доступ через DoB, адресу або номер телефону, тоді ви збираєтеся додавати індекси для кожного поля - і де це закінчується ?!
gbjbaanb

4
@gbjbaanb: це закінчується, коли люди припиняють додавати в продукт функції, які можуть бути "ніколи", залежно від вашої методики.
Стів Джессоп

1
@SteveJessop Я маю на увазі, що ви індексуєте відповідно до первинних стовпців, до яких ви хочете отримати доступ. Для таблиці людей у ​​вас може бути функція пошуку (якщо ви забудете своє ім’я користувача, наприклад, можете шукати електронну пошту), але після цього ви завжди використовуєте ідентифікатор. Тож ідентифікатор - єдиний, кому потрібна індексація. Якщо ви багато шукаєте в інших полях, вам може знадобитися індекс, це з’явиться вчасно, але, як правило, ви не хочете індексувати кожен стовпець лише тому, що хтось колись вирішив написати нестандартний запит, але ви можете використовувати інший механізм для цих "разових" випадків.
gbjbaanb

2
@gbjbaanb: звичайно, люди не повинні повторно шукати одне і те ж прізвище в таблиці, тому що це для них трохи зручніша ручка, ніж належна клавіша для таблиці. Я б сказав, що це так, незалежно від того, таблиця проіндексована на прізвище чи ні, насправді, оскільки в розтягуванні коду є щось дуже риболовецьке, що передбачає, що це все працює на "того самого користувача", але не в змозі висловити це в коді, пам’ятаючи ідентифікатор :-) Я уявляв випадки, коли потреба в зворотному пошуку не передбачалася, поки клієнт не згадав про це ...
Стів Джессоп,

26

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

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

По абсолютному мінімуму ви повинні завантажити свою базу даних правдоподібною кількістю тестових даних і перевірити чутливість програми. Це не передчасно, оскільки ви знаєте, що це відбудеться, і він буде вловлювати будь-які запити, які викликають безглуздо повільне сканування. Як каже AE у коментарі:

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

Принаймні, для таблиць, які планується вирощувати у використанні.

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


20

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

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

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

Яке загальне навантаження ?

Це може здатися очевидним або нудним, але на практиці це важливо. Якщо у вас є 10 запитів, які складають 98% вашої роботи (досить поширені, вірите чи ні), моя рекомендація буде важким аналізом перед виробництвом . Маючи реалістичні та репрезентативні дані, переконайтеся, що ці 10 запитів є настільки ж хорошими, наскільки це можливо ( ідеально - це витрата цінного часу і майже недосяжна).

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

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

Але ...

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

Як і більшість речей, існує здоровий баланс.

Як весела маленька сторона ... Плюралізація "Індексу"

"Індекси" призначені для фінансових людей

"Індекси" - це для нас


2
Для цього потрібно більше голосів. Я не міг більше погодитися.
RubberDuck

+1 за біт "про всяк випадок" (це була б передчасна оптимізація). Якби я міг би знову подати заявку на біт "загального навантаження".
Девід

Сподіваємося, ви заздалегідь знаєте, які 10 запитів належать 98%, а які - ні.
Paŭlo Ebermann

@ PaŭloEbermann Більшість СУБД мають можливість досить швидко та легко захоплювати цю інформацію. У цьому випадку немає приводу для того, щоб не знати.
Томас Стрінгер

@ThomasStringer Звичайно, це працює лише в тому випадку, якщо ваші тестові випадки перед початком виробництва якимось чином пов'язані з тим, що роблять реальні користувачі у виробництві.
Paŭlo Ebermann

4

Ні, це не передчасна оптимізація, але вона повинна бути виконана правильно, як і будь-яка оптимізація.

Ось що я б робив:

  1. Завантажте базу даних достатньою кількістю тестових даних, щоб імітувати виробниче навантаження. Ви не можете отримати цю 100% точність, але це нормально: просто введіть достатню кількість даних. Чи одна таблиця має фіксовану кількість даних? Завантажте його. Чи є у вас одна таблиця, яка містить багато даних, наприклад, яка таблиця містить запитання на цьому сайті? Завантажте кілька мільйонів записів, навіть якщо лише підроблені дані.
  2. Увімкніть профілювання на вашому сервері баз даних.
  3. Відбивайтеся від програми, використовуючи комбінацію автоматизованих сценаріїв (забезпечує обсяг) та реальних користувачів (вони знають, як розбити речі).
  4. Перегляньте дані профілювання. Певні запити повільні? Перевірте плани пояснень і перевірте, чи сервер бази даних говорить вам, що він хоче індекс, але його немає.

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

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


3

Дотримуватися перевірених зразків відомих проблем (наприклад, пошук запису за його ідентифікатором) не є передчасним. Це просто розумно.

Однак, індекси не завжди є простою справою. На етапі проектування часто важко знати, від яких індексів буде залежати ваш трафік і які будуть вузькі місця запису операцій. Отже, я б заперечував за використання деяких "очевидних" схем найкращого проектування схеми (використовуйте ПК, відповідний для розроблених моделей читання / запису та індексу FK); але не ставте індекс ні на що інше, поки цього не вимагатиме ваш стрес-тест.


Витратити додаткові 30 секунд на те, щоб зробити щось майже впевнене для підвищення продуктивності та малоймовірно, що це не завдасть шкоди, це не "передчасна оптимізація". Якщо 90% операцій над таблицею використовує певний стовпець як ключ, то або його індексація підвищить продуктивність, або продуктивність ніколи не буде досить повільною, а додавання коду для створення індексу може зайняти менше часу, ніж визначити, чи це дійсно необхідні.
supercat

@supercat "ніколи" ... Поки ви не почнете бачити тупики у виробничому середовищі ...
svidgen

Які реалістичні сценарії ви передбачаєте, які б відповідали 90% операцій, використовуючи стовпець як ключ, і де додавання індексу спричинило б тупик?
supercat

@supercat Я не впевнений, що я повністю розумію твої пошуки. Що стосується активної програми, майже будь-яке збільшення часу виконання або кількості ios може ввести тупикові місця. ... Але, до речі, наявність або відсутність індексу у більшості додатків є незначною, поки база даних не досягне критичного розміру та / або рівня одночасності. Наприклад, коли всі ваші індекси більше не вписуються в пам’ять ...
svidgen

1
Справа в тому, що важко знати, яким є ваш запит до тих пір, поки типові випадки використання не будуть проходити стрес-тест (або поки ви не побачите проблем із несподіваною поведінкою користувачів у виробництві). Якщо у вас є сторінка, яка відключає tablex.fieldy, але вона потрапляє лише один раз на кожні тисячі вставок ... Індекс може призвести до чистої деградації.
svidgen

2

Коли ваша заява буде звільнена, вже пізно.

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

Використовуйте результати своїх тестів на ефективність, щоб визначити, які індекси додати, і перевірити їх ефективність, повторивши тести на ефективність.


Коли програма виходить, це справді хороший час для підстроювання показників. Подивіться на цей сайт, stachexchange, ви можете поставити під заставу, що індекси змінилися довгий час після того, як він вийшов наживо.
ЛосМанос

@LosManos: Ніхто не платить за використання Stack Exchange.
Гонки легкості на орбіті

@LightnessRacesinOrbit: Про те, що рекламодавець, платить за використання Stack Exchange.

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

1

Хоча я не думаю, що кожен запит повинен бути оптимізований, індекси є настільки частиною RDBMS, що їх потрібно враховувати перед випуском. Коли ви виконуєте запит, на відміну від інших форм програмування, ви не говорите системі, як його виконати. Вони розробляють власні плани і майже завжди базують його на наявності індексу. Склад та обсяг даних будуть враховані також у наступні періоди.

Ось які речі я б розглядав:

  1. Є кілька запитів, які ви повинні визначити у своєму ранньому розвитку, які ви просто знаєте, що вони будуть часто використовуватися. Зосередьтеся на них.
  2. Будуть повільні запити. Спочатку індексуючи їх, ви зможете визначити, чи продуктивність все ще недостатньо швидка, а потім розглянути можливість зміни дизайну (денормалізація може бути передчасною). Я вважаю за краще це зробити до випуску. Ніхто не хоче системи, де потрібно 10 хвилин, щоб знайти щось в інвентарі.
  3. Індекси можуть покращити ефективність запитів, але вони не перешкоджають зміні даних.
  4. У багатьох системах є інструменти для аналізу ваших запитів, тому не бійтеся їх використовувати.

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

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


0

Це також залежить від того, скільки користувачів ви очікуєте. Ви обов'язково повинні пройти тестування навантаження та переконайтесь, що ваша база може не відставати від одночасних запитів від 10 до 100s до 1000s. Знову ж таки, це залежить від того, який обсяг трафіку ви очікуєте, і які області ви очікуєте використовувати більше, ніж інші.

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


0

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

Деякі питання, які вам потрібно задати:

  • Якими будуть межі дизайну для розміру кожної таблиці?

Якщо таблиці завжди будуть невеликими (скажімо, <100 рядків), це не буде катастрофою, якщо база даних повинна сканувати всю таблицю. Можливо, вигідно додати індекс, але для визначення цього потрібно трохи більше експертів або вимірювань.

  • Як часто буде виконуватися кожен запит і який необхідний час відповіді?

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

  • Чи вимагає запит шукати таблицю чимось окрім первинного ключа? Наприклад, фільтрування за діапазоном дат, приєднанням до іноземного ключа?

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

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