Лучше ли создать индекс до заполнения таблицы данными или после того, как данные будут на месте?


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

5 61

5 ответов:

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

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

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

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

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

  1. если вы добавляете данные в таблицу и после добавления индекса. Ваше время генерации индекса будет

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

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