PostgreSQL 32760绑定参数限制是否有解决方法?

时间:2019-01-16 23:07:49

标签: java postgresql hibernate jpa

我的存储库中有一个JPA方法,试图查找带有where子句的实体。问题是我有巨大的数据集,并且当我尝试在list子句中发送超过32k的元素时,我收到了错误消息。我发现这是PostgreSQL驱动程序的限制,但是我找不到解决方法。

我尝试了SELECT COUNT(*), CASE WHEN score > 0.1 THEN "low" CASE WHEN score > 0.3 THEN "medium" CASE WHEN score > 0.6 THEN "high" CASE WHEN score > 0.95 THEN "very_high" end as score_group FROM my_table GROUP BY score_group 请求,但很难发送8万条记录的3万条记录。有可能在我的清单清单where子句中发送超过3万个对象吗?

Pageable

1 个答案:

答案 0 :(得分:1)

不,您不想这样做,特别是如果您打算发送800万个标识符。解决IN语句或绑定参数限制的效率很低。请考虑以下内容:

  1. 成千上万的绑定参数将导致兆字节的SQL。将SQL文本发送到数据库将花费大量时间。实际上,与按照Tom's answer to "Limit and conversion very long IN list: WHERE x IN ( ,,, ...)" question执行查询相比,数据库读取SQL文本所花费的时间可能更长。

  2. SQL解析效率很低。不仅百万字节的SQL文本需要花费时间来读取,而且随着绑定参数计数的增加,每个查询通常将使用不同数量的绑定参数。这种独特的绑定参数计数将导致分别解析和计划每个查询(请参见this article which explains it)。

  3. SQL语句中对绑定参数有硬限制。您刚刚发现了32760。

对于这些类型的查询,通常最好创建temporary tables。在查询之前创建一个新的临时表,将所有标识符插入其中,并将其与实体表联接。此联接将等效于IN条件,但SQL文本较短。

重要的是要了解这800万个标识符从何处加载。如果要在上一个查询中从数据库中提取这些查询,只是要将它们传递回下一个查询,则很可能要编写一个存储过程。您目前的方法可能存在缺陷,JPA并非总是适合该工作的工具。