sql - Postgres 和 Ruby 的续集 : Empty array in where-clause getting converted to slow query

标签 sql ruby postgresql sequel

我正在使用优秀的 Sequel ORM,并且在某个时候我生成了一个 ID 数组,并且我正在尝试检索具有这些 ID 的用户。例如

user_ids = [1, 2, 3]
User.where(id: user_ids).all
# (0.004223s) SELECT * FROM "users" WHERE ("id" IN (1, 2, 3))

但有时,用户列表是空的,我有效得到的是:

User.where(id: []).all
# (0.421287s) SELECT * FROM "users" WHERE ("id" != "id")

结果是正确的(即没有返回行),但查询速度慢了两个数量级。

在具有数百万行的表上,可能需要几秒钟的时间才能返回。

我很好奇为什么首先会生成这个查询,但我也很好奇为什么 Postgres 查询规划器似乎没有检测到这种矛盾并立即返回一个空数据集。

是否有一个巧妙的解决方案,或者我必须检查所有数组是否为空?

我正在使用 Ruby 2.0.0、Sequel 4.24.0 和 Postgres 9.3.6。

最佳答案

有一个closed issue on github关于这种行为。

我同意 jeremyevans 的观点,即不需要修复,因为很明显,结果将并且应该始终为空。此外,您可能会认为 PostgreSQL 应该足够聪明来优化这样的查询,并且不应该进行全表扫描。

因此,恕我直言,在代码中修复此行为以避免完全调用数据库更有意义:

user_ids.present? ? User.where(id: user_ids) : []

关于sql - Postgres 和 Ruby 的续集 : Empty array in where-clause getting converted to slow query,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33991876/

相关文章:

sql - Oracle是否使用短路评估?

postgresql - 无法创建 PG sql 函数

postgresql - Postgres pl/java 注意事项

mysql - 在一段时间内查找最大项目的算法建议

sql - Oracle中删除表中的重复行

ruby-on-rails - 如何验证其他表中的相应条目是否存在

ruby - 类型 2 虚拟主机是否受到与主机操作系统相同的限制?

ruby-on-rails - TimeWithZone & Time.zone.now 集成测试失败

python - 使用 Django 在另一台服务器上创建 PostgreSQL 数据库

c# - 在 C# 中丢失与 sql server 2008 的连接