PostgreSQL: Какой эффективный способ обновить записи 3м? - PullRequest
1 голос
/ 19 августа 2009

Разработчик моей работы (много лет назад) переместил столбец body из нашей таблицы comments во вторичную таблицу comment_extensions в качестве некоторой отрывочной оптимизации догадок. Кажется, не рекомендуется делать объединение каждый раз, когда мы хотим отобразить комментарий, поэтому я попытаюсь переместить этот столбец обратно в нашу таблицу comments и выполнить некоторые тесты.

Моя проблема в том, что это обновление сканируется. Я давал ему поработать час, прежде чем его отключить, опасаясь, что это займет всю ночь.

UPDATE comments SET body = comment_extensions.body 
                FROM comment_extensions 
                WHERE comments.id = comment_extensions.comment_id;

Это база данных PostgreSQL 8.1, а comment_extensions.comment_id проиндексирован.

Какие-нибудь предложения по ускорению запуска?

Ответы [ 3 ]

2 голосов
/ 19 августа 2009

Как насчет этого?

http://www.postgresql.org/docs/8.1/interactive/sql-createtableas.html

CREATE TABLE joined_comments
    AS SELECT c.id, c.author, c.blablabla, ce.body
    FROM comments c LEFT JOIN comment_extensions ce
    ON c.id = ce.comment_id;

Это создаст новую таблицу join_comments. Этого может быть почти достаточно (вам нужно будет еще пересоздать индексы и т. Д.), Но я помню, что в Postgres 8.1 есть ошибка, связанная с тем, как создаются последовательные столбцы (извините, не могу найти ссылку).

Поэтому я предлагаю, чтобы после того, как у вас появилась эта новая объединенная таблица, вы скопировали файл BINARY из этой таблицы join_comments, создали новую таблицу комментариев, в которой с самого начала указано, что id является SERIAL, а затем скопировали из этого двоичного файла. файл в новую таблицу комментариев. Затем воссоздайте индексы.

2 голосов
/ 19 августа 2009

Ну, для академического вопроса, почему это опрометчиво? Какой процент поиска включает необходимость знать информацию о комментарии?

Мое предложение: обновлять небольшими партиями (10000 строк за раз?). Это может все еще занять всю ночь. В зависимости от характера вашей системы вам также может понадобиться реализовать логику отключения, которая не позволяет системе обновлять или извлекать данные из таблицы расширений во время этой миграции.

Большие базы данных так больно;)

1 голос
/ 19 августа 2009

Вы можете получить выгоду от отключения журнала при этом. Если это тест в непроизводственной таблице, вам, вероятно, не нужна защита, которую предоставляет вам файл журнала.

Если в комментариях есть индекс или ключ, то его нужно отбросить до обновления и заново создать его после.

Является ли поле comments.body фиксированной шириной char (N) или это varchar? Varchar раньше был медленнее, чем char (), и я подозреваю, что это все еще так. Так что используйте символ, а не varchar.

Если вы делаете выбор, который объединяет данные в файл данных (скажем, в кавычки csv), и пишете скрипт, чтобы превратить его в INSERTS, то очистите таблицу комментариев и загрузите ее с INSERTS, которая может быть быстрее, чем ваш запрос. есть, хотя индекс comments.id помогает скорости.

3e6 записи займет некоторое время независимо от этого.

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