AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 106264
Accepted
Erwin Brandstetter
Erwin Brandstetter
Asked: 2015-07-08 16:25:17 +0800 CST2015-07-08 16:25:17 +0800 CST 2015-07-08 16:25:17 +0800 CST

带有位图索引扫描的查询计划中的“重新检查条件:”行

  • 772

这是对上一个问题的评论的衍生:

  • Postgres 9.4.4 查询需要永远

Recheck Cond:使用 PostgreSQL 9.4,在查询计划输出的位图索引扫描之后似乎总是有一行EXPLAIN。

就像在EXPLAIN引用问题的输出中一样:

->  Bitmap Heap Scan on table_three  (cost=2446.92..19686.74 rows=8159 width=7)
      Recheck Cond: (("timestamp" > (now() - '30 days'::interval)) AND (client_id > 0))
      ->  BitmapAnd  (cost=2446.92..2446.92 rows=8159 width=0)
            ->  Bitmap Index Scan on table_one_timestamp_idx  (cost=0.00..1040.00 rows=79941 width=0)
                  Index Cond: ("timestamp" > (now() - '30 days'::interval))
            ->  Bitmap Index Scan on fki_table_three_client_id  (cost=0.00..1406.05 rows=107978 width=0)
                  Index Cond: (client_id > 0)

或者在EXPLAIN ANALYZE一个简单的、巨大的表(很少work_mem)的输出中:

EXPLAIN ANALYZE SELECT * FROM aa WHERE a BETWEEN 100000 AND 200000;
Bitmap Heap Scan on aa  (cost=107.68..4818.05 rows=5000 width=4) (actual time=27.629..213.606 rows=100001 loops=1)
  Recheck Cond: ((a >= 100000) AND (a <= 200000))
  Rows Removed by Index Recheck: 758222
  Heap Blocks: exact=693 lossy=3732
  ->  Bitmap Index Scan on aai  (cost=0.00..106.43 rows=5000 width=0) (actual time=27.265..27.265 rows=100001 loops=1)
        Index Cond: ((a >= 100000) AND (a <= 200000))

这是否意味着必须在位图索引扫描后再次检查索引条件?
我们还能从EXPLAIN输出中学到什么?

postgresql index
  • 2 2 个回答
  • 14161 Views

2 个回答

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2015-07-08T16:52:22+08:002015-07-08T16:52:22+08:00

    正如@Chris 对引用问题的正确评论:

    一点调查似乎表明重新检查条件总是打印在 中EXPLAIN,但实际上仅在 work_mem足够小以至于位图变得有损时才执行。想法? http://www.postgresql.org/message-id/[email protected]

    虽然这一切都是真的,核心开发人员 Heikki Linnakangas 是一流的资源,但这篇文章可以追溯到 2007 年(Postgres 8.2)。这是Michael Paquier 的一篇博客文章,其中详细解释了 Postgres 9.4,其中的输出EXPLAIN ANALYZE已通过更多信息得到改进。

    该Recheck Cond:行始终用于位图索引扫描。basic 的输出EXPLAIN不会告诉我们更多信息。我们从EXPLAIN ANALYZE问题的第二个引用中可以看到更多信息:

    Heap Blocks: exact=693 lossy=3732
    

    在总共 4425 个数据页(块)中,有 693 个完全存储元组(包括元组指针),而其他 3732 个页在位图中是有损的(只是数据页)。当work_mem不足以存储从索引扫描构建的整个位图时,就会发生这种情况(无损)。

    对于有损共享中的页面,必须重新检查索引条件,因为位图只记住要获取的页面,而不是页面上的确切元组。并非页面上的所有元组都一定会通过索引条件,有必要实际重新检查条件。

    这是pgsql 黑客上讨论新增内容的线程。作者Etsuro Fujita 提供了一个公式,用于计算最小值work_mem以避免有损位图条目和随后的条件重新检查。对于具有多个位图扫描的复杂情况,该计算不可靠,因此它不用于从EXPLAIN. 它仍然可以作为简单案例的估计。

    附加线BUFFERS:

    此外,当使用BUFFERSoption:运行时,EXPLAIN (ANALYZE, BUFFERS) ...添加了另一行,如:

    Buffers: shared hit=279 read=79
    

    这表明有多少基础表(和索引)是从缓存中读取的(shared hit=279)以及必须从磁盘中获取多少(read=79)。如果您重复查询,对于不太大的查询,“读取”部分通常会消失,因为在第一次调用之后现在所有内容都被缓存了。第一个调用告诉您已经缓存了多少。随后的调用显示您的缓存可以处理多少(当前)。

    还有更多选择。关于BUFFERS选项的手册:

    具体来说,包括命中、读取、弄脏和写入的共享块的数量,命中、读取、弄脏和写入的本地块的数量,以及读取和写入的临时块的数量。

    继续阅读,还有更多。
    这是源代码中的输出选项列表。

    • 24
  2. Chris
    2015-07-08T17:07:45+08:002015-07-08T17:07:45+08:00

    欧文,因为这是我们之前在评论线程中的讨论,所以我决定再深入一点......

    我有一个来自合理大小的表的非常简单的查询。我通常有足够work_mem的,但在这种情况下,我使用了命令

    SET work_mem = 64;
    

    设置一个非常小的work_mem和

    SET work_mem = default;
    

    让我的work_mem背对我的查询足够大。

    解释并重新检查条件

    因此,仅使用EXPLAINas运行我的查询

    EXPLAIN 
    SELECT * FROM olap.reading_facts
    WHERE meter < 20;
    

    我获得了低和高的结果work_mem:

    低的work_mem

    Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32)
      Recheck Cond: (meter < 20)
      ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0)
            Index Cond: (meter < 20)
    

    高的work_mem

    Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32)
      Recheck Cond: (meter < 20)
      ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0)
            Index Cond: (meter < 20)
    

    长话短说,EXPLAIN仅如预期的那样,查询计划表明可能有 Recheck 条件,但我们不知道是否会实际计算。

    解释分析和重新检查条件

    当我们包含ANALYZE在查询中时,结果会告诉我们更多关于我们需要知道的内容。

    低的work_mem

    Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32) (actual time=3.130..13.946 rows=51840 loops=1)
      Recheck Cond: (meter < 20)
      Rows Removed by Index Recheck: 86727
      Heap Blocks: exact=598 lossy=836
      ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0) (actual time=3.066..3.066 rows=51840 loops=1)
            Index Cond: (meter < 20)
    

    高的work_mem

    Bitmap Heap Scan on reading_facts  (cost=898.92..85632.60 rows=47804 width=32) (actual time=2.647..7.247 rows=51840 loops=1)
      Recheck Cond: (meter < 20)
      Heap Blocks: exact=1434
      ->  Bitmap Index Scan on idx_meter_reading_facts  (cost=0.00..886.96 rows=47804 width=0) (actual time=2.496..2.496 rows=51840 loops=1)
            Index Cond: (meter < 20)
    

    同样,正如预期的那样,包含ANALYZE向我们揭示了一些非常重要的信息。在低work_mem情况下,我们看到索引重新检查删除了一些行,并且我们有lossy堆块。

    结论?(或缺乏)

    EXPLAIN不幸的是,它本身似乎不足以知道是否真的需要重新检查索引,因为在位图堆扫描期间为了保留页面而删除了一些行 ID。

    使用EXPLAIN ANALYZE它可以很好地诊断中等长度查询的问题,但如果查询需要很长时间才能完成,那么运行EXPLAIN ANALYZE以发现您的位图索引由于不足而转换为有损work_mem仍然是一个困难的约束。我希望有一种方法可以EXPLAIN从表统计信息中估计发生这种情况的可能性。

    • 12

相关问题

  • 我在索引上放了多少“填充”?

  • PostgreSQL 中 UniProt 的生物序列

  • RDBMS 上的“索引”是什么意思?[关闭]

  • 如何在 MySQL 中创建条件索引?

  • PostgreSQL 9.0 Replication 和 Slony-I 有什么区别?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve