【问题标题】:Can't query for more than 100 IDs with PostgreSQL不能用 PostgreSQL 查询超过 100 个 ID
【发布时间】:2021-07-05 10:11:32
【问题描述】:

我正在从 MySQL 迁移到 PostgreSQL,但出现以下错误:

PG::TooManyArguments: 错误:不能将超过 100 个参数传递给函数

当运行这样的查询时:

 Project.where(id: ids)

翻译成什么

"SELECT \"projects\".* FROM \"projects\" WHERE \"projects\".\"id\" IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100) ORDER BY FIELD(projects.id, '1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','65','66','67','68','69','70','71','72','73','74','75','76','77','78','79','80','81','82','83','84','85','86','87','88','89','90','91','92','93','94','95','96','97','98','99','100')"

对我来说,通过特定 ID 进行查询是一个常见的用例,它与 MySQL 配合得很好。有什么方法可以让 PostgreSQL 工作?

我在 docker 容器上使用 PostgreSQL 13.2。

【问题讨论】:

  • 据我所知FIELD() 不是 Postgres 中的函数。那么,您是否在使用某种第三方插件?还有为什么不只是ORDER BY projects.id
  • id 是从哪里来的?使用子查询可能会更容易
  • 我没有使用任何第三方库,只是来自 dockerhub 的原始 PostgreSQL。 ID 并不总是连续的,它只是在这种情况下来自特定测试。

标签: ruby-on-rails postgresql activerecord


【解决方案1】:

根据您遇到的错误,原因是功能而不是查询本身。您可以将 32K 参数传递给查询,它将起作用(2byte int 限制)。至于函数,postgres 默认有 100 个 arg 限制(在编译期间设置)。您可以尝试从源代码编译并将该数字设置为更高的值(我不建议这样做,除非您真的了解后果)。

最好的方法可能是研究如何替换执行和修改的FIELD() 函数,以免遇到问题。您可以更改您的系统,以便您可以使用 DB 中的列进行排序吗?这样您就不需要传递这些 ID 进行排序。或者,如果您必须使用 ID,那么使用 CASE 进行排序怎么样,例如这个 SO 问题:Simulating MySQL's ORDER BY FIELD() in Postgresql

【讨论】:

  • 这至少应该是 PostgreSQL 中一个可配置的、易于更改的选项,这个限制令人大失所望。
  • 澄清一下,100 arg 限制是函数调用可以具有的参数数量,并且可能有充分的理由(猜测性能或内存)它不是那么容易改变。也许你应该改变你的方法,这样你就不会遇到这个限制。您可以生成CASE 语句而不是使用自定义FIELD() 函数吗?像这样:stackoverflow.com/questions/1309624/…
  • 这很有趣,因为它在 PostgreSQL 10 上运行得非常好,我现在正在获得最新版本,而这个功能曾经可以工作,不幸的是,这可能就是答案。
【解决方案2】:

我能找到的唯一“修复”是将 PostgreSQL docker 映像降级到不会发生此错误的 11.11

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    • 2021-09-11
    • 1970-01-01
    • 2020-07-07
    • 1970-01-01
    相关资源
    最近更新 更多