Rail 的 default_scope 对性能的影响

Effects of Rail's default_scope on performance

default_scope 不按 ID 对记录进行排序时,是否会显着降低 Rails 应用程序的速度?

例如,我有一个使用 PostgreSQL 的 Rails(当前为 3.1)应用程序,其中几乎每个模型都有一个 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 by name,我可能会遭受什么性能损失?我是否应该担心这 default_scope 会影响应用程序性能?

你的问题没有抓住重点。默认范围本身只是 Ruby 执行的几微秒,导致将 order by 子句添加到发送到 PostgreSQL 的每个 SQL 语句中。

所以你的问题实际上是在询问无序查询和有序查询之间的性能差异。

Postgresql documentation is pretty explicit。对未索引字段的有序查询比无序查询慢得多,因为(毫不奇怪),PostgreSQL 必须在对结果进行 return 排序之前对结果进行排序,首先创建临时 table 或索引来包含结果。这很容易成为查询时间的 4 倍,甚至更多。

如果您引入索引只是为了实现快速排序,您仍然需要为每次插入和更新时维护索引付费。除非它是主索引,否则排序访问仍然涉及随机查找,这实际上可能 比创建临时 table 慢 。这也在 Postgres 文档中进行了讨论。

简而言之,切勿向不需要的 SQL 查询添加顺序子句(除非您喜欢等待​​数据库)。

注意:我怀疑一个简单的 find() 是否会附加顺序,因为它必须 return 正好是一个结果。您可以通过启动 rails console、发出查找并观察生成的 SQL 滚动来非常快速地验证这一点。但是,whereall 肯定会被订购,因此肯定比需要的要慢。