当前位置: 首页 > 面试题库 >

使用IN的postgres查询非常慢

施景同
2023-03-14
问题内容

我有一个表,其中有一个索引(A列,B列)。我正在运行一个查询,如下所示:

SELECT * FROM table WHERE (A, B) IN ((a_1, b_1), (a_2, b_2), ..., (a_5000, b_5000))

这个查询很慢!该计划如下所示:

Bitmap Heap Scan on table
  Recheck Cond: (((A = a_1) AND (B = b_1)) OR ((A = a_2) AND (B = b_2)) OR ...
  ->  BitmapOr
        ->  Bitmap Index Scan on idx
              Index Cond: ((A = a_1) AND (B = b_1))
        ->  Bitmap Index Scan on idx
              Index Cond: ((A = a_2) AND (B = b_2))
        ...(5000 other Bitmax Index Scan)

Postgres似乎没有一次对5000个值进行一次索引扫描,而是一次对5000个值进行了一次索引扫描,这解释了为什么查询如此缓慢。

实际上,这样做是更快的方法

SELECT * FROM table WHERE A IN (a_1, ..., a_5000)

获取结果,然后在应用程序内的B列上进行过滤(python)。

我真的更希望结果已经由Postgres在合理的运行时间下进行过滤。有解决方法吗?


问题答案:

尝试加入CTE:

with value_list (a,b) as (
  values 
      (a_1, b_1), 
      (a_2, b_2), ..., 
      (a_5000, b_5000) 
)
select *
from table t
  join value_list v on (t.a, t.b) = (v.a, v.b);

(这假定您在值列表中没有重复项)



 类似资料:
  • 问题内容: 我有一个MySQL查询(Ubu 10.04,Innodb,Core i7、16Gb RAM,SSD驱动器,优化的MySQL参数): 表em_link_data有大约700万行,em_link有数千行。此查询大约需要 18秒 才能完成。但是,如果我替换子查询的结果并执行以下操作: 那么查询将在不到1毫秒的时间内运行。仅子查询在不到1毫秒的时间内运行,因此索引了列linkid。 如果我将查

  • 键->字符串 principal_name->string 别名->字符串集合 ....... 我还在principal_name、别名和key上添加了索引。 当我试图导入Article类型节点和Author类型节点之间的关系时,问题就出现了。 有办法用Cypher做到这一点吗?

  • 问题内容: 我正在尝试执行这样的查询: 问题是我要过滤的ID列表不是恒定的,并且每次执行时都必须不同。我还需要转义这些id,因为它们可能来自不受信任的来源,尽管我实际上将转义查询中的所有内容,而不管该来源的可信度如何。 节点的Postgres似乎与绑定参数专门工作:; 如果我具有已知数量的值(),这将起作用,但不能直接用于数组:,因为似乎对数组参数没有任何特殊处理。 根据数组中的项目数动态构建查询

  • 我正在尝试从我的Java项目中执行以下查询。我正在使用MySQL和数据存储,并已将Hikari CP配置为数据源。 MySQL连接字符串: 当我从MySQL workbench执行同样的查询时,它在0.5秒内返回结果。 然而,当我在JPA存储库或Spring JDBC模板中执行相同的操作时,几乎需要50秒的时间。 此查询有2个IN子句,其中状态集合只有3个项目,而标识值集合有10000个项目。 当

  • 我正在对一个小表执行一个简单的查询 系统表只有三列(Id、Name、Progress)和1300行。 我获取数据的代码是: 这段代码在JTable中显示日期大约需要15秒,而如果在phpmyadmin中执行查询,则需要不到1秒。

  • 问题内容: 为什么简单地更新此表以添加列需要一个多小时?该表有1500万行。它具有2个索引和一个键主键。ALTER TABLE查询现在已处于“复制到tmp表”状态1小时15分钟。 表: 问题答案: 对于非常大的表,MySQL的ALTER TABLE性能可能会成为问题。MySQL通过创建一个具有所需新结构的空表,将旧表中的所有数据插入新表中,然后删除旧表来执行大多数更改。这可能会花费很长的时间,特别