gpt4 book ai didi

ruby-on-rails - Rails ActiveRecord where 子句在本地与生产中使用 .first 与 .last

转载 作者:行者123 更新时间:2023-11-29 14:33:38 26 4
gpt4 key购买 nike

我使用 Rails 5 和 Postgres。我有一个表名 buckets,没有任何列被索引。在我的本地机器上,我创建了 55,000 条虚拟记录。我只需要获取一条记录,其中 bucket_type 等于 PR 且 issued_date 为 nil(有 7 种不同的 bucket_type,例如 PR、CA、US、EU、VN、BU 和 GY),因此我尝试了 2 个不同的查询,其中一个是 .first 和一个带有 .last 的,看看哪个执行得更快。

Bucket.where({issued_date: nil, bucket_type: 'PR'}).first 这个查询大约需要 1.5 毫秒

Bucket.where({issued_date: nil, bucket_type: 'PR'}).last 这个查询大约需要 6.5 毫秒

然而在生产环境中(Heroku),buckets 表中有 210 万条记录,结果却相反:

Bucket.where({issued_date: nil, bucket_type: 'PR'}).first 这个查询大约需要 750 毫秒

Bucket.where({issued_date: nil, bucket_type: 'PR'}).last 这个查询大约需要 150 毫秒

我有两个问题:

  1. 为什么 .first.lastwhere 子句之后的性能在本地与生产环境中不同?
  2. 有没有比上述查询更好的方法来获取 bucket_type 等于 PR 且 issued_date 为 nil 的记录而无需添加任何索引bucket_typeissued_date,还是两列?

最佳答案

我真的不能告诉你第一个问题的答案,但是对于第二个问题,好吧,你应该使用 limit

让我们看看区别:

User.where(is_disabled: 0).first
# Oracle
SELECT * FROM (
SELECT "USERS".* FROM "USERS" WHERE "USERS"."IS_DISABLED" = :a1
ORDER BY "USERS"."ID" ASC
) WHERE ROWNUM <= :a2
# MariaDB
SELECT `users`.* FROM `users` WHERE `users`.`is_disabled` = 0
ORDER BY `users`.`id` ASC LIMIT 1

您在 oracle 中看到首先选择所有用户,然后将查询包装为仅选择第一个。这当然很糟糕,MySQL/MariaDB 不会那样做。但按 user_id 排序(well rails 不支持 MariaDB)

User.where(is_disabled: 0).limit(1)
# Oracle
SELECT "USERS".* FROM "USERS" WHERE "USERS"."IS_DISABLED" = :a1
AND ROWNUM <= :a2
#MariaDB
SELECT `users`.* FROM `users` WHERE `users`.`is_disabled` = 1 LIMIT 1

在 Oracle 中,从一开始就只选择一个用户,这样速度更快。MariaDB 不对用户进行排序,这也更快。

附言这可能会根据使用的数据库而改变,但 limit 是无论如何都要走的路。但是只要我们不知道使用的数据库,您的问题 1 就无法解决。此外,这应该分为两个问题

关于ruby-on-rails - Rails ActiveRecord where 子句在本地与生产中使用 .first 与 .last,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48181562/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com