Rails的ActiveRecord的where子句中使用。首先VS在本地与生产。去年

问题描述 投票:0回答:1

我使用Rails的5和Postgres。我有一个表名buckets,没有任何列被索引。在我的本地机器上创建虚拟55000记录。我只需要得到一个纪录有bucket_type等于PR和issued_date是零(有7种不同的bucket_type如PR,CA,美国,欧盟,VN,BU和GY),所以我尽量2个不同的查询一个与.first和一个与.last,看看哪一个执行得更快。

Bucket.where({issued_date: nil, bucket_type: 'PR'}).first这个查询花费大约为1.5ms

Bucket.where({issued_date: nil, bucket_type: 'PR'}).last与此查询需要约6.5ms

然而,当生产(Heroku的),用水桶表2.1万人次的纪录,结果出来了相反的:

Bucket.where({issued_date: nil, bucket_type: 'PR'}).first这个查询花费大约为750ms

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

我有2个问题:

  1. 为什么.first条款后.lastwhere的性能是当地不同​​VS生产?
  2. 有什么比上面的查询更好的方式来获得一个纪录有bucket_type等于PR和issued_date是零,而无需任何索引添加到任何bucket_typeissued_date,或两列?
ruby-on-rails ruby postgresql heroku query-performance
1个回答
2
投票

我真的不能告诉你那么第一个问题的答案,但第二,好,你应该使用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(以及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

在这里,在甲骨文只有一个用户会从一开始,这是更快选择。 MariaDB的不这也是更快的用户进行排序。

附:这可以根据使用的数据库可能改变,但limit是去反正方式。但是你的问题1是不可解的,只要我们不知道所使用的数据库。此外,应在两个问题劈裂

© www.soinside.com 2019 - 2024. All rights reserved.