我正在使用优秀的 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/