0

default_scope习惯于不按 ID 排序记录会显着降低 Rails 应用程序的速度吗

例如,我有一个使用 PostgreSQL 的 Rails(当前为 3.1)应用程序,其中几乎每个模型都有一个default_scope按其名称命名的排序记录:

default_scope order('users.name')

现在因为default_scope's order records by namerather by 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影响应用程序性能吗?

4

1 回答 1

4

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

因此,您的问题实际上是在询问无序查询和有序查询之间的性能差异。

Postgresql 文档非常明确。无索引字段的有序查询比无序查询慢得多,因为(毫不奇怪)PostgreSQL 必须在返回结果之前对结果进行排序,首先创建临时表或索引来包含结果。这很容易成为查询时间的 4 倍,甚至可能更多。

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

简而言之,永远不要在不需要的 SQL 查询中添加 order 子句(除非您喜欢等待​​数据库)。

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

于 2015-04-09T03:19:39.970 回答