我使用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个问题:
.first
条款后.last
和where
的性能是当地不同VS生产?bucket_type
或issued_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(以及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是不可解的,只要我们不知道所使用的数据库。此外,应在两个问题劈裂