2017-02-10 44 views
0

我很难检查以找到两个查询的执行速度,解释分析和基准,因为我得到一个查询超时,但我不知道这个查询是造成这种情况。在rails查询ActiveRecord计数分析

queue_count = purchase.purchase_items.where("queue_id = ?", queue.id).count 

相同的SQL查询

SELECT COUNT(*) FROM "purchase_items" WHERE "purchase_items"."purchase_id" = 1241422 AND (queue_id = 3479783) 

,所以我不得不删除计数,然后我得到一个解决方案,采取在阵列中的所有记录,并做计数,然后我得到了这样的

queue_count = purchase.purchase_items.where("queue_id = ?", queue.id).all.count 
查询

相同的SQL查询

SELECT "purchase_items".* FROM "purchase_items" WHERE "purchase_items"."purchase_id" = 1241422 AND (queue_id = 3479783) 

终于得到了一些细微的变化,当我用查询分析和基准检查,所以这是正确的方式?还是我做错了什么?

回答

1

在性能方面,第二次查询将会非常糟糕。它会在内存中加载全部记录并使用Ruby对它们进行计数。数据库旨在快速完成这样的工作。

为了分析查询,您可以在Psql控制台中执行EXPLAIN ANALYZE。我的远景是你缺少一些索引(在purchase_id和queue_id上​​)。您可以通过运行来查看:

EXPLAIN ANALYZE SELECT COUNT(*) FROM purchase_items WHERE purchase_id = 1241422 AND (queue_id = 3479783) 

如果您看到PostgreSQL正在扫描整个表,那么性能将不会最佳。尝试添加索引:

CREATE INDEX purchase_id_purchase_items_idx ON purchase_items (purchase_id); 
CREATE INDEX queue_id_purchase_items_idx ON purchase_items (queue_id); 

,并使用EXPLAIN ANALYZE检查的表现又如何。但永远不会加载到Ruby的所有记录做他们的简单.count

+0

我已经有该索引,但是当我分析EXPLAIN ANALYZE SELECT COUNT(*)FROM purchase_items时,还有一件事WHERE purchase_id = 1241422 AND(queue_id = 3479783)这个查询在第一次点击时显示执行时间:1.088 ms,second命中这个显示0.148毫秒,是否有任何逻辑背后检查一次或第一次命中执行时间是正确的? – django

+1

你需要运行它几次并计算f.e.平均 - 一次尝试不足以获得正确的数据。如果它是1毫秒或0.1毫秒,那么它非常快,绝对不是瓶颈 – Esse