【问题标题】:An index scan is going to the heap for fetching results when only the indexed column is queried仅查询索引列时,索引扫描将进入堆以获取结果
【发布时间】:2021-01-06 18:17:41
【问题描述】:

我在 Postgres 中创建了以下包含 500 万行的测试表

create table temp_test(
id serial, 
latitude float, longitude float,name varchar(32),
questionaire jsonb, city varchar(32), country varchar(32)
);

我使用以下查询在此表中生成了随机数据

CREATE OR REPLACE FUNCTION
random_in_range(INTEGER, INTEGER) RETURNS INTEGER
AS $$
    SELECT floor(($1 + ($2 - $1 + 1) * random()))::INTEGER;
$$ LANGUAGE SQL;


insert into temp_test(latitude,longitude,name,questionaire,city,country)
Select random_in_range(-180,180),random_in_range(-180,180),md5(random()::text),'["autism","efg"]',md5(random()::text)
,md5(random()::text)
from generate_series(1,5000000);

列 'id' 有一个 btree 索引

CREATE INDEX id_index ON temp_test (id);

当我尝试仅使用具有索引的“id”进行查询并“解释分析”查询时

explain analyse select id from temp_test where id = 10000;

我得到以下结果:

此查询的执行时间约为 0.049 秒,如果我重新运行相同的查询(考虑到数据库正在缓存),我会在大约相似的持续时间内得到结果。

从结果中,我看到即使我在索引列上查询而不获取任何其他列(我知道这不切实际),为什么在索引中存在信息时使用堆内存。

如果我从索引中提取信息,我希望查询不会触及堆。

我在这里缺少什么吗?任何帮助,将不胜感激。提前致谢!

【问题讨论】:

  • 您没有描述在桌子上运行真空(或提供您的版本,这可能很重要)。
  • @jjanes 我运行了“VCCUM FULL VERBOSE”,并且正在使用 Postgres 11(来自 Azure 的托管云数据库服务)。查询性能没有任何改进。正如这个视频中建议的那样youtube.com/watch?v=POBmmmFjIe4我不确定我是否可以访问共享内存
  • 为什么你认为执行时间是 1 秒?您的查询计划说它花费了 0.049 毫秒和额外的 0.133 毫秒进行计划。总共不到 0.2 毫秒。这甚至不到 1 秒。
  • @FrankHeikens- 糟糕的是,我正在查看我的 SQL 工作台上的响应时间。我会纠正我的问题

标签: postgresql indexing backend heap-memory database-indexes


【解决方案1】:

查询可能正在访问堆以检查可见性 ma。运行 vacuum full verbose 并查看 postgres 的内容。这将使行对所有事务可见。有时 postgres 无法完全运行真空,原因或其他如此冗长的帮助。

【讨论】:

  • 当然不是 VACUUM FULL。它不仅无缘无故地缓慢且无益,而且实际上是有害的,因为它会清除开始时设置的所有可见性位。不过,VACUUM VERBOSE 是个好主意。
【解决方案2】:

我找到了解决方案,我在桌子上抽真空

vacuum temp_test;

而不是运行“Vacuum Full Verbose”

虽然它有效,但我想知道这两个命令之间有什么区别

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-04
    • 1970-01-01
    • 2021-06-09
    • 2011-06-28
    • 2017-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多