比较不同哈希值的两个值的最快方法是什么?

时间:2019-02-05 22:37:52

标签: ruby-on-rails ruby

我正在尝试比较两个散列以查看值是否匹配,以便我可以协调一些数据。

我有一个现有帐户的哈希值,我需要根据现有帐户检查它们是否存在,以查看是否需要插入该帐户。

# Reconcile Adaccounts
def self.reconcileAdaccounts(ad_accounts, user_id)

    # These are the accounts that exist
    existing_accounts = FbAdaccount.active
                                    .select("fb_id")
                                    .where("user_id = ?", user_id)
                                    .as_json

    ad_accounts.each do |ad_account|

        if #here i would need to check if ad_account["account_id"] matches one of the existing records

            p "This one already exists"
            p ad_account["account_id"]
        else

            p "I need to create this one"
            p ad_account["account_id"]
        end

    end

end

我可能有嵌套循环,但这似乎不是最好的解决方案,我还尝试寻找任何可以做到这一点的Rails API函数,但我没有找到一个。

最有效的方法是什么?

1 个答案:

答案 0 :(得分:0)

您要寻找的是find_or_create_by。我还将该调用包装在事务中,因此所有这些仅一次在数据库中命中一次-在单个查询中。

def self.reconcileAdaccounts(ad_accounts, user_id)
  FbAdaccount.transaction do
    ad_accounts.each do |ad_account|
      FbAdaccount.active
                 .select('fb_id')
                 .where('user_id = ?', user_id)
                 .find_or_create_by(ad_account['account_id'])
    end
  end
end

交易

交易不会神奇地改变查询,但会将其包装在一起,以便要么全部发生,要么根本不发生。

使用以下代码:

numbers = (3..7).to_a

Ear.transaction do
  numbers.each do |number|
    Ear.find_or_create_by(bla: number)
  end
end

请注意BEGINCOMMIT语句。它们表示呼叫的开始和结束位置。

 (0.1ms)  BEGIN
Ear Load (0.5ms)  SELECT  "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2  [["bla", 3], ["LIMIT", 1]]
Ear Create (0.8ms)  INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["bla", 3], ["created_at", "2019-02-05 23:17:28.157989"], ["updated_at", "2019-02-05 23:17:28.157989"]]
Ear Load (0.2ms)  SELECT  "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2  [["bla", 4], ["LIMIT", 1]]
Ear Create (0.2ms)  INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["bla", 4], ["created_at", "2019-02-05 23:17:28.160838"], ["updated_at", "2019-02-05 23:17:28.160838"]]
Ear Load (0.1ms)  SELECT  "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2  [["bla", 5], ["LIMIT", 1]]
Ear Create (0.2ms)  INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["bla", 5], ["created_at", "2019-02-05 23:17:28.162241"], ["updated_at", "2019-02-05 23:17:28.162241"]]
Ear Load (0.2ms)  SELECT  "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2  [["bla", 6], ["LIMIT", 1]]
Ear Create (0.2ms)  INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["bla", 6], ["created_at", "2019-02-05 23:17:28.163794"], ["updated_at", "2019-02-05 23:17:28.163794"]]
Ear Load (0.2ms)  SELECT  "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2  [["bla", 7], ["LIMIT", 1]]
Ear Create (0.2ms)  INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["bla", 7], ["created_at", "2019-02-05 23:17:28.165589"], ["updated_at", "2019-02-05 23:17:28.165589"]]
 (40.9ms)  COMMIT

现在这里是相同的代码,只是没有用于包装它的事务:

numbers = (20..25).to_a

numbers.each do |number|
  Ear.find_or_create_by(bla: number)
end

注意总数为BEGINCOMMIT的消息:

Ear Load (249.3ms)  SELECT  "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2  [["bla", 20], ["LIMIT", 1]]
(73.4ms)  BEGIN
Ear Create (48.7ms)  INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["bla", 20], ["created_at", "2019-02-06 00:12:35.754374"], ["updated_at", "2019-02-06 00:12:35.754374"]]
(79.8ms)  COMMIT
Ear Load (0.4ms)  SELECT  "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2  [["bla", 21], ["LIMIT", 1]]
(0.2ms)  BEGIN
Ear Create (77.7ms)  INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["bla", 21], ["created_at", "2019-02-06 00:12:35.918461"], ["updated_at", "2019-02-06 00:12:35.918461"]]
(0.3ms)  COMMIT
Ear Load (0.2ms)  SELECT  "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2  [["bla", 22], ["LIMIT", 1]]
(0.2ms)  BEGIN
Ear Create (2.7ms)  INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["bla", 22], ["created_at", "2019-02-06 00:12:36.003822"], ["updated_at", "2019-02-06 00:12:36.003822"]]
(110.1ms)  COMMIT
Ear Load (0.3ms)  SELECT  "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2  [["bla", 23], ["LIMIT", 1]]
(0.2ms)  BEGIN
Ear Create (0.3ms)  INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["bla", 23], ["created_at", "2019-02-06 00:12:36.125187"], ["updated_at", "2019-02-06 00:12:36.125187"]]
(37.0ms)  COMMIT
Ear Load (0.2ms)  SELECT  "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2  [["bla", 24], ["LIMIT", 1]]
(0.2ms)  BEGIN
Ear Create (0.4ms)  INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["bla", 24], ["created_at", "2019-02-06 00:12:36.168414"], ["updated_at", "2019-02-06 00:12:36.168414"]]
(72.4ms)  COMMIT
Ear Load (0.3ms)  SELECT  "ears".* FROM "ears" WHERE "ears"."bla" = $1 LIMIT $2  [["bla", 25], ["LIMIT", 1]]
(1.7ms)  BEGIN
Ear Create (0.4ms)  INSERT INTO "ears" ("bla", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["bla", 25], ["created_at", "2019-02-06 00:12:36.249285"], ["updated_at", "2019-02-06 00:12:36.249285"]]
(121.2ms)  COMMIT