Какая разница в производительности между fetchall_hashref и fetchall_arrayref из DBI? - PullRequest
5 голосов
/ 23 февраля 2010

Я пишу несколько сценариев Perl для манипулирования большими объемами (всего около 42 миллионов строк, но это не будет сделано одним ударом) данных в двух базах данных PostgreSQL.

Для некоторых моих запросов имеет смысл использовать fetchall_hashref, потому что у меня есть синтетические ключи. Однако в других случаях я собираюсь использовать массив из трех столбцов в качестве уникального ключа.

Это заставляет меня задуматься о различиях в производительности между fetchall_arrayref и fetchall_hashref. Я знаю, что в обоих случаях все идет в память, поэтому выбор нескольких ГБ данных, вероятно, не очень хорошая идея, но, кроме того, в документации очень мало рекомендаций, когда речь идет о производительности.

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

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

Ответы [ 2 ]

5 голосов
/ 23 февраля 2010

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

Насколько я помню, перебор с fetchrow_arrayref и использование bind_columns - это самый быстрый (с наименьшими затратами DBI) способ чтения возвращаемых данных.

3 голосов
/ 23 февраля 2010

Первый вопрос: действительно ли вам нужно использовать fetchall в первую очередь? Если вам не нужны все 42 миллиона строк в памяти одновременно, не читайте их все сразу! bind_columns и fetchrow_arrayref - это, как правило, путь, когда это возможно, как уже указывалось.

Предполагая, что fetchall действительно необходимо, моя интуитивная интуиция заключается в том, что fetchall_arrayref будет незначительно быстрее, поскольку массив представляет собой более простую структуру данных и не требует вычисления хэшей вставленных ключей, но экономия время будет меньше времени чтения базы данных, поэтому оно вряд ли будет значительным.

Требования к памяти - совсем другое дело. Структура, возвращаемая fetchall_hashref, является хешем id => row, причем каждая строка представляется как хэш field name => field value. Если вы получите 42 миллиона строк, это означает, что ваш список имен полей повторяется в каждом из 42 миллионов наборов хеш-ключей ... Это потребует гораздо большего объема памяти для хранения, чем массив массивов массивов, возвращаемых fetchall_arrayref. (Если, конечно, DBI не работает с tie для оптимизации структуры fetchall_hashref, я полагаю.)

...