首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PostgreSQL:简单的等式查询,不返回索引列的结果

PostgreSQL:简单的等式查询,不返回索引列的结果
EN

Database Administration用户
提问于 2017-11-06 15:27:36
回答 1查看 889关注 0票数 2

我有一个非常大的表(约140米行),有五列:

代码语言:javascript
复制
CREATE TABLE IF NOT EXISTS citations 
(
   citing_id text,
   citing_issn text,
   cited_id text,
   cited_issn text,
   year int
);

citing_idcited_id上都有散列索引,这两种索引都没有空值(已确认),但是在这些列中选择相等的查询无论如何都会返回零结果。即使这个查询(我认为它可以在任何填充的表中工作)也会返回零行:

代码语言:javascript
复制
SELECT * 
FROM citations 
WHERE citing_id IN (SELECT citing_id 
                    FROM citations LIMIT 1) 
LIMIT 100;

但是,对非索引列的相同查询与预期完全相同:

代码语言:javascript
复制
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

编辑

第一个查询(在索引列上,不返回任何行)的查询计划是:

代码语言:javascript
复制
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)

对于第二个查询(在非索引列上,返回预期结果):

代码语言:javascript
复制
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)
EN

回答 1

Database Administration用户

发布于 2017-11-07 11:31:19

citing_id和cited_id上都有散列索引,这两种索引都没有空值(已确认),但是在这些列中选择相等的查询无论如何都会返回零结果。

索引可能已损坏。哈希索引只在PostgreSQL 10之后才被WAL记录。在以前的版本中,它们没有那种机制可以使它们在不干净的关闭过程中保持正确。

为9.5创建索引上的文档有以下警告:

哈希索引操作目前没有WAL日志记录,因此,如果有未写入的更改,则可能需要在数据库崩溃后使用重新索引重新生成散列索引。此外,对哈希索引的更改不会在初始基本备份之后通过流复制或基于文件的复制复制,因此它们对随后使用它们的查询给出了错误的答案。哈希索引也没有在实时恢复期间正确地恢复.出于这些原因,目前不鼓励使用散列索引。

考虑升级到PostgreSQL 10,同时REINDEX哈希索引。

票数 2
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/190219

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档