Почему PostgreSQL съедает все мое драгоценное место на жестком диске?

StackOverflow https://stackoverflow.com/questions/409727

Вопрос

Я только что закончил передачу как можно большего количества данных о ссылочной структуре, касающихся Википедии (на английском языке).По сути, я скачал кучу дампов SQL из Википедии. последний репозиторий дампов.Поскольку я использую PostgreSQL вместо MySQL, я решил загрузить все эти дампы в свою базу данных, используя команды оболочки конвейера.

Во всяком случае, в одной из этих таблиц 295 миллионов строк:тот ссылки на страницы стол;он содержит все гиперссылки внутри вики.Со своего ноутбука с помощью pgAdmin III я отправил следующую команду на сервер базы данных (другой компьютер):

SELECT pl_namespace, COUNT(*) FROM pagelinks GROUP BY (pl_namespace);

Это длится уже час или около того.Дело в том, что почтмейстер, кажется, съедает все больше и больше моего очень ограниченного HD-пространства.Я думаю, что на данный момент он съел около 20 ГБ.Ранее я экспериментировал с файлом postgresql.conf, чтобы придать ему большую гибкость производительности (т.е.пусть использует больше ресурсов), ибо он работает с 12 ГБ ОЗУ.Я думаю, что я увеличил в четыре раза большинство байтов и связанных с ними переменных этого файла, думая, что для выполнения своей задачи потребуется больше оперативной памяти.

Однако БД, похоже, не использует много оперативной памяти.Используя системный монитор Linux, я вижу, что почтмейстер использует 1,6 ГБ общей памяти (ОЗУ).В любом случае, мне было интересно, можете ли вы, ребята, помочь мне лучше понять, что он делает, потому что, похоже, я действительно не понимаю. как PostgreSQL использует HD-ресурсы.

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

Не стесняйтесь спрашивать меня о более подробной информации, спасибо.

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

Решение

Вероятно, проблема связана с GROUP BY.Чтобы выполнить группировку, база данных должна отсортировать строки, чтобы объединить повторяющиеся элементы.Индекс, вероятно, не поможет.Предварительный расчет:

Предположим, что каждая строка занимает 100 байт пространства, это 29 500 000 000 байт или около 30 ГБ памяти.Он не может уместить все это в памяти, поэтому ваша система зависает, что замедляет операции в 1000 или более раз.Ваше место на жестком диске может исчезнуть в пространстве подкачки, если оно использует файлы подкачки.

Если вам нужно выполнить этот расчет только один раз, попробуйте разбить его на более мелкие подмножества данных.Предполагая, что pl_namespace имеет числовое значение и находится в диапазоне от 1 до 295 миллионов, попробуйте что-то вроде этого:

SELECT pl_namespace, COUNT(*)
FROM pagelinks
WHERE pl_namespace between 1 and 50000000
GROUP BY (pl_namespace);

Затем сделайте то же самое для 50000001-100000000 и так далее.Объедините свои ответы вместе с помощью UNION или просто сведите результаты в таблицу с помощью внешней программы.Забудьте, что я писал об индексе, который не помогает GROUP BY;здесь индекс поможет предложению WHERE.

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

Что точно утверждает, что занимает всего 9,5 МБ ОЗУ?Мне это кажется маловероятным — общая память почти наверняка является ОЗУ, которая распределяется между различными процессами Postgres.(Насколько я помню, каждый клиент представляет собой отдельный процесс, хотя прошло много времени, поэтому я могу сильно ошибаться.)

Есть ли у вас индекс на pl_namespace столбец?Если имеется очень много различных результатов, я могу представить, что этот запрос будет довольно тяжелым для таблицы из 295 миллионов строк без индекса.Однако 10 ГБ — это очень много.Вы знаете, в какие файлы он пишет?

Хорошо, вот суть:

предложение GROUP BY сделало индекс недействительным, поэтому постмастер (серверный процесс postgresql) решил создать группу таблиц (23 ГБ таблиц), которые находились в каталоге $PGDATA/base/16384/pgsql_tmp.

При изменении файла postgresql.conf я разрешил postgreSQL использовать 1,6 ГБ ОЗУ (теперь я удвою это число, поскольку у него есть доступ к 11,7 ГБ ОЗУ);процесс postmaster действительно использовал 1,6 ГБ ОЗУ, но этого было недостаточно, как и каталог pgsql_tmp.

Как отметил Барри Браун, поскольку я выполнял эту команду SQL только для того, чтобы получить некоторую статистическую информацию о распределении ссылок между pagelinks.namespaces, я мог бы запросить часть из 296 миллионов ссылки на страницы (это то, что они делают для опросов).

Когда команда вернула набор результатов, все временные таблицы были автоматически удалены, как ни в чем не бывало.

Спасибо за вашу помощь, ребята!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top