我有一个非常大的表(约140米行),有五列:
CREATE TABLE IF NOT EXISTS citations
(
citing_id text,
citing_issn text,
cited_id text,
cited_issn text,
year int
);citing_id和cited_id上都有散列索引,这两种索引都没有空值(已确认),但是在这些列中选择相等的查询无论如何都会返回零结果。即使这个查询(我认为它可以在任何填充的表中工作)也会返回零行:
SELECT *
FROM citations
WHERE citing_id IN (SELECT citing_id
FROM citations LIMIT 1)
LIMIT 100;但是,对非索引列的相同查询与预期完全相同:
SELECT *
FROM citations
WHERE citing_issn IN (SELECT citing_issn
FROM citations LIMIT 1)
LIMIT 100;数据是使用COPY命令从CSV文件加载的,我怀疑索引值的末尾可能有额外的隐藏字符--使用WHERE citing_id LIKE '<id>%'查询非常慢(散列索引对部分字符串没有帮助),但返回正确的结果。不过,上面的第一个查询无论如何都应该有效,除非我弄错了。
我在MacOS 10.13.1上运行Postgres 9.5.3.0
第一个查询(在索引列上,不返回任何行)的查询计划是:
Limit (cost=0.03..1.38 rows=100 width=58)
-> Nested Loop (cost=0.03..265.83 rows=19751 width=58)
-> HashAggregate (cost=0.03..0.04 rows=1 width=17)
Group Key: citations_1.citing_id
-> Limit (cost=0.00..0.02 rows=1 width=17)
-> Seq Scan on citations citations_1 (cost=0.00..3164425.68 rows=148131768 width=17)
-> Index Scan using citations_citing_id on citations (cost=0.00..265.14 rows=65 width=58)
Index Cond: (citing_id = citations_1.citing_id)对于第二个查询(在非索引列上,返回预期结果):
Limit (cost=0.04..139.54 rows=100 width=58)
-> Hash Semi Join (cost=0.04..3581836.35 rows=2567617 width=58)
Hash Cond: (citations.citing_issn = citations_1.citing_issn)
-> Seq Scan on citations (cost=0.00..3164425.68 rows=148131768 width=58)
-> Hash (cost=0.03..0.03 rows=1 width=10)
-> Limit (cost=0.00..0.02 rows=1 width=10)
-> Seq Scan on citations citations_1 (cost=0.00..3164425.68 rows=148131768 width=10)发布于 2017-11-07 11:31:19
citing_id和cited_id上都有散列索引,这两种索引都没有空值(已确认),但是在这些列中选择相等的查询无论如何都会返回零结果。
索引可能已损坏。哈希索引只在PostgreSQL 10之后才被WAL记录。在以前的版本中,它们没有那种机制可以使它们在不干净的关闭过程中保持正确。
为9.5创建索引上的文档有以下警告:
哈希索引操作目前没有WAL日志记录,因此,如果有未写入的更改,则可能需要在数据库崩溃后使用重新索引重新生成散列索引。此外,对哈希索引的更改不会在初始基本备份之后通过流复制或基于文件的复制复制,因此它们对随后使用它们的查询给出了错误的答案。哈希索引也没有在实时恢复期间正确地恢复.出于这些原因,目前不鼓励使用散列索引。
考虑升级到PostgreSQL 10,同时REINDEX哈希索引。
https://dba.stackexchange.com/questions/190219
复制相似问题