Rails pluck - недокументированные возможности
Выбор колонки таблицы сразу в массив
Метод :pluck
был представлен в Rails 3.2. Он позволяет производить выборку данных сразу в массив, минуя тяжелые объекты ActiveRecord. Даже если вы уже знаете что такое :pluck - уверен, вам будет, что узнать из этой статьи.
Rails до появления :pluck
Нам приходилось выбирать нужные объекты и потом маппить их массив. Минус такого подхода в том, что в промежуточном этапе нам нужно выделить память для массива объектов, что может довольно критически сказаться на производительности, если таких объектов много
User.select(:email)
User Load (0.4ms) SELECT "users"."email" FROM "users"
=> #, #, #]>
User.select(:email).map(&:email)
User Load (0.4ms) SELECT "users"."email" FROM "users"
=> ["bbb@bbb.bb", "vvv@vvv.vv", "aaa@aaa.aa"]
Pluck - выборка в массив быстрее и проще
В самой простой форме :pluck
позволяет выбрать данные из колонки в массив, Однако в отличии от :select
- он не строит инстансы ActiveRecord объектов, что значительно ускоряет скорость выборки и экономие памяти. У меня были случаи когда код через map работал 10 минут, а с pluck обрабатывался всего за минуту.
User.pluck(:email)
(0.4ms) SELECT "users"."email" FROM "users"
=> ["bbb@bbb.bb", "vvv@vvv.vv", "aaa@aaa.aa"]
Но, начиная с Rails 4 :pluck стал умнее и позволяет принимать более сложные парамеры
User.pluck(:email, :created_at)
(0.5ms) SELECT "users"."email", "users"."created_at" FROM "users"
=>
Чего нет в документации!
В документации не написано, что pluck может также принимать SQL. Это позволит использовать его в более сложных случаях, Когда например, нужно выбрать значение из 2х таблиц. В принципе pluck и так это умеет, но только если выбирается столбец имеющий унакальное для 2х столбцов имя. С created_at так не болучится, Более того, возможно там понадобится выполнить какие-либо преобразования в процессе выборки и мы можем сделать их средаствами SQL
User.pluck(<<-PLUCK)
UPPER(email)
PLUCK
(20.0ms) SELECT UPPER(email)
FROM "users"
=> ["BBB@BBB.BB", "VVV@VVV.VV", "AAA@AAA.AA"]
Выводы
pluck - простой и высокоэффективный метод маппинга данных из базы в массив, Он позволяет увеличить производительность в несколько раз и выполнить базовые преобразования средствами SQL
Что нужно помнить используя pluck?
- pluck вернет массив а не ActiveRecord::Relation, он должен быть последним в цепочке
- Всегда нужно помнить какие операции выполняются базой данных, а какие - ruby кодом. User.distinct.pluck(:emal) быстрее чем User.pluck(:email).uniq
- Pluck может производить выборку по нескольким полям User.pluck(:created_at, :email)
- Для простых преобразований или чтобы разрешить конфликт в имени столбца - можно передать запрос строкой User.joins(:projects).pluck(“projects.created_at”)
Комментарии