Лучше создать индекс перед заполнением таблицы данными или после того, как данные на месте? - PullRequest
70 голосов
/ 11 сентября 2010

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

Ответы [ 5 ]

89 голосов
/ 11 сентября 2010

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

Пример синтаксиса (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 с (более чем в два раза медленнее)

8 голосов
/ 11 сентября 2010

Вероятно, лучше создать индекс после добавления строк. Мало того, что это будет быстрее, но балансировка дерева, вероятно, будет лучше.

Редактировать"балансировка", вероятно, не лучший выбор терминов здесь. В случае b-дерева оно сбалансировано по определению. Но это не значит, что b-дерево имеет оптимальную компоновку. Распределение дочерних узлов в пределах родительского узла может быть неравномерным (что приведет к более высокой стоимости в будущих обновлениях), и глубина дерева может оказаться глубже, чем необходимо, если во время обновлений балансировка не выполняется аккуратно Если индекс создается после добавления строк, он, скорее всего, будет иметь лучшее распределение. Кроме того, индексные страницы на диске могут иметь меньшую фрагментацию после построения индекса. Немного больше информации здесь

2 голосов
/ 11 сентября 2010

Это не имеет значения для этой проблемы, потому что:

  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 голос
/ 04 августа 2017

Индексы, созданные после, в большинстве случаев работают намного быстрее.Пример: 20 миллионов строк с полным текстом на varchar (255) - (Business Name) Индекс на месте при импорте строк - совпадение с продолжительностью до 20 секунд в худшем случае.Удаление индекса и повторное создание - совпадение с продолжительностью менее 1 секунды каждый раз

0 голосов
/ 11 сентября 2010

Я не уверен, что это действительно будет иметь значение для эффективности индекса, поскольку в обоих случаях вы вставляете новые данные в индекс. Сервер не будет знать, насколько неравномерным будет индекс, до тех пор, пока он не будет построен. По скорости, очевидно, делать вставки без индекса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...