可以 default_scope
用于不按ID 对Rails应用程序显着减慢记录订单吗?
例如,我有一个使用PostgreSQL的Rails(目前是3.1)应用程序,其中几乎每个Model都有一个default_scope
排序记录的名称:
default_scope order('users.name')
现在因为default_scope
的订单记录在name
而不是ID
, 我担心我可能会遭受重大的性能损失正常查询运行时。 例如:
User.find(5563401)
或
@User.where('created_at = ?', 2.weeks.ago)
或
User.some_scope_sorted_best_by_id.all
在上面的示例中,我的模型上default_scope
乘name
可能会导致性能下降?我应该关注影响应用程序性能的default_scope
吗?
答案 0 :(得分:4)
你的问题忽略了这一点。默认作用域本身只是几微秒的Ruby执行,导致order by子句被添加到发送到PostgreSQL的每个SQL语句中。
所以你的问题实际上是在询问无序查询和有序查询之间的性能差异。
Postgresql documentation is pretty explicit。对无索引字段的有序查询比无序字段慢得多,因为(毫不奇怪),PostgreSQL必须在返回结果之前对结果进行排序,首先创建临时表或索引以包含结果。这可能很容易成为查询时间的4倍,可能更多。
如果您引入索引只是为了实现快速排序,那么您仍然需要为每次插入和更新维护索引。除非它是主要索引,否则排序访问仍然涉及随机搜索,实际上可能比创建临时表更慢。这也在Postgres文档中讨论过。
简而言之,永远不要将一个order子句添加到不需要它的SQL查询中(除非您喜欢等待数据库)。
注意:我怀疑一个简单的find()
将附加订单,因为它必须返回一个结果。您可以通过启动rails console
,发出查找并观察生成的SQL滚动来快速验证这一点。但是,where
和all
肯定会被订购,因此肯定会比所需的慢。