Я пишу некоторые сценарии Perl для управления большим объемом (всего приблизительно 42 миллиона строк, но это не будет сделано в одном хите) данных в двух базах данных PostgreSQL.
Для некоторых моих запросов это проявляет здравый смысл использовать fetchall_hashref
потому что у меня есть синтетические ключи. Однако в других случаях я собираюсь иметь, используют массив трех столбцов как уникальный ключ.
Это имеет меня задающийся вопросом о различиях в производительности между fetchall_arrayref
и fetchall_hashref
. Я знаю, что в обоих случаях все входит к памяти, настолько выбирающие несколько ГБ данных, вероятно, не являются хорошей идеей, но кроме которого там, кажется, очень мало руководства в документации когда дело доходит до производительности.
Мой поиск с помощью Google был неудачен поэтому, если бы кто-либо может указать на меня в направлении некоторого общего исследования качества работы, я был бы благодарен.
(Я знаю, что мог сравнить этого сам, но в dev целях у меня нет доступа к машине, которая имеет идентичное оборудование к производству, которое является, почему я ищу общие руководящие принципы или даже лучшие практики).
Первый вопрос заключается в том, действительно ли вам нужно использовать фетчалл
в первую очередь. Если вам не нужны сразу все 42 миллиона строк в памяти, не считывайте их все сразу! bind_columns
и fetchrow_arrayref
обычно подходят везде, где это возможно, как уже указывалось ysth.
Если предположить, что fetchall
действительно необходим, моя интуиция подсказывает, что fetchall_arrayref
будет немного быстрее, поскольку массив представляет собой более простую структуру данных и не требует вычисления хэшей вставленных ключей, но экономия времени будет меньше, чем время чтения базы данных, поэтому маловероятно.
А вот требования к памяти - совсем другое дело. Структура, возвращаемая fetchall_hashref
, является хешем id => row
, причем каждая строка представлена как хеш field name => field value
. Если вы получаете 42 миллиона строк, это означает, что ваш список имен полей повторяется в каждом из 42 миллионов наборов хэш-ключей ... Это потребует гораздо больше памяти для хранения, чем массив массивов массивов, возвращаемых fetchall_arrayref
. (Полагаю, если DBI не творит чудеса с tie
для оптимизации структуры fetchall_hashref
.)
Большинство вариантов выбора между методами выборки зависят от того, в каком формате вы хотите, чтобы данные заканчивались, и какой объем работы, которую вы хотите, чтобы DBI выполнял за вас.
Насколько я помню, повторение с помощью fetchrow_arrayref и использование bind_columns - это самый быстрый (с наименьшими накладными расходами DBI) способ чтения возвращаемых данных.