Postgresql Postgres在大约13亿行的表中查找唯一值的速度不是很快

Postgresql Postgres在大约13亿行的表中查找唯一值的速度不是很快,postgresql,performance,indexing,unique,Postgresql,Performance,Indexing,Unique,所以我有一个(记录的)表,有两列a,B,包含文本。 它们基本上包含相同类型的信息,因为数据来自于两列 我希望有一个包含所有唯一值的表(因此我将列作为主键),而不关心列。但是当我要求博士后做什么的时候 插入到新_表(值)中,从旧_表中选择一个冲突(值)不做任何事情;(稍后,B列的情况与此相同) 它使用了1个cpu内核,并且仅以大约5 MB/s的速度从我的SSD读取数据。几小时后我就停止了 我怀疑这可能是因为b树速度慢,所以我在新表中的唯一属性上添加了一个hashindex。但它仍然最大限度地使用1

所以我有一个(记录的)表,有两列a,B,包含文本。 它们基本上包含相同类型的信息,因为数据来自于两列

我希望有一个包含所有唯一值的表(因此我将列作为主键),而不关心列。但是当我要求博士后做什么的时候

插入到新_表(值)中,从旧_表中选择一个冲突(值)不做任何事情;(稍后,B列的情况与此相同)

它使用了1个cpu内核,并且仅以大约5 MB/s的速度从我的SSD读取数据。几小时后我就停止了

我怀疑这可能是因为b树速度慢,所以我在新表中的唯一属性上添加了一个hashindex。但它仍然最大限度地使用1个内核,从ssd读取数据的速度仅为每秒5 MB。我的java程序可以将哈希设置为至少150MB/s,所以postgres应该比5MB/s快很多,对吗?我分析了我的旧表,并将我的新表解锁,以便更快地插入,但它仍然使用1个核心,读取速度非常慢

如何解决这个问题

编辑:这是对上述查询的解释。似乎postgres正在使用它为主键创建的b树,而不是我的(更快,不是吗??)散列索引

Insert on users  (cost=0.00..28648717.24 rows=1340108416 width=14)
  Conflict Resolution: NOTHING
  Conflict Arbiter Indexes: users_pkey
  ->  Seq Scan on games  (cost=0.00..28648717.24 rows=1340108416 width=14)

冲突上的
机制主要用于解决并发引起的冲突。您可以在这样的“静态”情况下使用它,但其他方法将更有效

只需在第一位插入不同的值:

insert into new_table(value) 
    select A from old_table union
    select B from old_table 
为了提高性能,在填充表之前不要添加主键。并将work_mem设置为可信的最大值

我的java程序可以将哈希设置为至少150 MB/s

这就是完全在内存中使用哈希集。PostgreSQL索引是基于磁盘的结构。它们确实受益于缓存,但这仅限于此,取决于您没有告诉我们的硬件和设置

似乎postgres正在使用它为主键创建的b树,而不是我的(更快,不是吗??)散列索引

Insert on users  (cost=0.00..28648717.24 rows=1340108416 width=14)
  Conflict Resolution: NOTHING
  Conflict Arbiter Indexes: users_pkey
  ->  Seq Scan on games  (cost=0.00..28648717.24 rows=1340108416 width=14)

它只能使用定义约束的索引,即btree索引,因为哈希索引不能支持主键约束。您可以使用散列索引定义一个排除约束,但这只会使它变得更慢。一般来说,散列索引并不比PostgreSQL中的btree索引“快很多”。

i7-8750H 6核2.2GHz基本超读,16GB RAM 2666,在基准测试期间具有3GB读写的SSD,大量的可用空间,GPU无关紧要,我想是吧,GPU无关紧要。核心计数也不支持,因为并行查询目前不支持INSERT语句。结果集有多少行?16GB可能不足以将它们全部散列,除非输入大部分是重复的。结果集的大小略大于1.083.000.000