Вопрос

Я запускал ОБНОВЛЕНИЕ для таблицы, содержащей 250 миллионов строк с индексом 3';это ОБНОВЛЕНИЕ использует другую таблицу, содержащую 30 миллионов строк.Он работает уже около 36 часов.Мне интересно, есть ли способ узнать, насколько это близко к завершению, потому что, если он планирует потратить миллион дней, чтобы сделать свое дело, я убью его;но если ему понадобится еще день или два, я позволю ему работать.Вот команда-запрос:

UPDATE pagelinks SET pl_to = page_id
    FROM page
    WHERE 
        (pl_namespace, pl_title) = (page_namespace, page_title)
        AND
        page_is_redirect = 0
;

EXPLAIN здесь не является проблемой, и я упоминаю только о том, что большая таблица имеет несколько индексов, чтобы в некоторой степени оправдать, сколько времени требуется для ее ОБНОВЛЕНИЯ.Но вот ОБЪЯСНЕНИЕ в любом случае:

Merge Join  (cost=127710692.21..135714045.43 rows=452882848 width=57)
  Merge Cond: (("outer".page_namespace = "inner".pl_namespace) AND ("outer"."?column4?" = "inner"."?column5?"))
  ->  Sort  (cost=3193335.39..3219544.38 rows=10483593 width=41)
        Sort Key: page.page_namespace, (page.page_title)::text
        ->  Seq Scan on page  (cost=0.00..439678.01 rows=10483593 width=41)
              Filter: (page_is_redirect = 0::numeric)
  ->  Sort  (cost=124517356.82..125285665.74 rows=307323566 width=46)
        Sort Key: pagelinks.pl_namespace, (pagelinks.pl_title)::text"
        ->  Seq Scan on pagelinks  (cost=0.00..6169460.66 rows=307323566 width=46)

Теперь я также отправил параллельную команду-запрос, чтобы УДАЛИТЬ один из ссылки на страницы' индексы;конечно, он ждет завершения ОБНОВЛЕНИЯ (но мне все равно хотелось попробовать!).Следовательно, я не могу ВЫБРАТЬ что-либо из ссылки на страницы из-за страха повредить данные (если только вы не думаете, что было бы безопасно завершить процесс постмастера DROP INDEX?).

Поэтому мне интересно, есть ли таблица, которая будет отслеживать количество мертвых кортежей или что-то в этом роде. Было бы неплохо узнать, насколько быстро и насколько далеко находится UPDATE в выполнении своей задачи.

Тхх (PostgreSQL не такой умный, как я думал;нужна эвристика)

Это было полезно?

Решение

Вы читали документацию PostgreSQL для "Использование EXPLAIN", чтобы интерпретировать вывод, который вы показываете?

Я не являюсь постоянным пользователем PostgreSQL, но я только что прочитал этот документ, а затем сравнил его с EXPLAIN вывод, который вы показываете.Твой UPDATE запрос, похоже, не использует индексы и вынужден выполнять сканирование таблиц для сортировки обоих page и pagelinks.Этот сорт, без сомнения, достаточно велик, чтобы потребовать временные файлы на диске, которые, я думаю, создаются под вашим temp_tablespace.

Затем я вижу прочитанные предполагаемые страницы базы данных.Высший уровень этого EXPLAIN вывод говорит (cost=127710692.21..135714045.43).Здесь устройства имеют доступ к дисковому вводу-выводу.Таким образом, для этого ему потребуется получить доступ к диску более 135 миллионов раз. UPDATE.

Обратите внимание, что даже диски со скоростью вращения 10 000 об/мин и временем поиска 5 мс могут выполнять в лучшем случае 200 операций ввода-вывода в секунду при оптимальных условиях.Это будет означать, что ваш UPDATE потребуется 188 часов (7,8 дней) дискового ввода-вывода, даже если вы сможете поддерживать насыщенный дисковый ввод-вывод в течение этого периода (т. е.непрерывное чтение/запись без перерывов).Это невозможно, и я ожидаю, что фактическая пропускная способность будет ниже, по крайней мере, на порядок, тем более, что вы, несомненно, тем временем использовали этот сервер для всевозможных других работ.Так что я предполагаю, что вы прошли лишь часть пути UPDATE.

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

Что касается вашего DROP INDEX, я предполагаю, что он просто блокируется, ожидая эксклюзивного доступа к таблице, и пока он находится в этом состоянии, я думаю, вы, вероятно, сможете его убить.

Другие советы

Это очень старое решение, но если вам нужен способ отслеживать обновления...Помните, что последовательности затрагиваются глобально, поэтому вы можете просто создать одну для мониторинга этого обновления в другом сеансе, выполнив следующие действия:

create sequence yourprogress; 

UPDATE pagelinks SET pl_to = page_id
    FROM page
    WHERE 
        (pl_namespace, pl_title) = (page_namespace, page_title)
        AND
        page_is_redirect = 0 AND NEXTVAL('yourprogress')!=0;

Затем в другом сеансе просто сделайте это (не беспокойтесь о транзакциях, поскольку последовательности затрагиваются глобально):

select last_value from yourprogress;

Это покажет, сколько строк затронуто, и вы сможете оценить, сколько времени вам понадобится.

В конце перезапустите последовательность, чтобы сделать еще одну попытку:

alter sequence yourprogress restart with 1;

Или просто скиньте:

drop sequence yourprogress;

Вам нужны индексы или, как отметил Билл, потребуется выполнить последовательное сканирование всех таблиц.

CREATE INDEX page_ns_title_idx on page(page_namespace, page_title);
CREATE INDEX pl_ns_title_idx on pagelink(pl_namespace, pl_title);
CREATE INDEX page_redir_idx on page(page_is_redirect);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top