Чи краще створювати індекс перед заповненням таблиці даними або після того, як дані будуть на місці?


87

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

Відповіді:


113

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

Синтетичний приклад (PostgreSQL 9.1, машина для повільної розробки, один мільйон рядків):

CREATE TABLE test1(id serial, x integer);
INSERT INTO test1(id, x) SELECT x.id, x.id*100 FROM generate_series(1,1000000) AS x(id);
-- Time: 7816.561 ms
CREATE INDEX test1_x ON test1 (x);
-- Time: 4183.614 ms

Вставте, а потім створіть індекс - близько 12 с

CREATE TABLE test2(id serial, x integer);
CREATE INDEX test2_x ON test2 (x);
-- Time: 2.315 ms
INSERT INTO test2(id, x) SELECT x.id, x.id*100 FROM generate_series(1,1000000) AS x(id);
-- Time: 25399.460 ms

Створити індекс, а потім вставити - приблизно 25,5 сек (більш ніж у два рази повільніше)


5
+1, індекси помітно уповільнюють операцію, що включає 100 мільйонів завдань вставки рядка, тому краще скинути їх і відтворити.
code4life

10

Можливо, краще створити індекс після додавання рядків. Це не тільки буде швидше, але й балансування дерев, мабуть, буде кращим.

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


2

Це не має значення для цієї проблеми, оскільки:

  1. Якщо ви додаєте дані спочатку до таблиці, а після неї - індекс. Час створення вашого індексу буде O(n*log(N))довшим (де nдодаються рядки). Оскільки тоді генерування дерева - це час, O(N*log(N))якщо ви розділите це на старі дані, і нові дані, які ви отримаєте, O((X+n)*log(N))їх можна просто перетворити, O(X*log(N) + n*log(N))і в цьому форматі ви просто побачите, на що ви будете чекати додатково.
  2. Якщо додати індекс і після нього помістити дані. Кожен рядок (у вас є nнові рядки) ви отримуєте довший час, O(log(N))щоб вставити додатковий час, необхідний для регенерації структури дерева після додавання в нього нового елемента (стовпець індексу з нового рядка, оскільки індекс вже існує і додано новий рядок, тоді індекс потрібно відновити до збалансованого Структура, ця вартість O(log(P))де P- індекс степеня (елементи в індексі) ). У вас є nнові рядки, тоді нарешті у вас є n * O(log(N))потім O(n*log(N))підсумок додаткового часу.

1

Індекси, створені після, в більшості випадків набагато швидші. Приклад: 20 мільйонів рядків із повним текстом на varchar (255) - Індекс (Назва компанії) на місці під час імпортування рядків - збіг проти зайняття до 20 секунд у гірших випадках. Падіння індексу та повторне створення - збігайтеся з тим, щоб забирати щонайменше менше 1 секунди


-2

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

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