代码之家  ›  专栏  ›  技术社区  ›  Joe23

多列索引不用于仅索引扫描,但部分索引是

  •  2
  • Joe23  · 技术社区  · 8 年前

    我的问题是,当具有等效信息的部分索引(我认为)是,为什么多列索引不用于仅索引扫描。

    桌子:

    CREATE TABLE test 
    (
      id      INT,
      descr   TEXT,
      flag    BOOLEAN
    );
    
    INSERT INTO test
    SELECT GENERATE_SERIES(1,100000) AS id,
           MD5(RANDOM()::TEXT) AS descr,
           (RANDOM() < 0.1) AS flag;
    
    SELECT *
    FROM test LIMIT 10;
    

    内容示例:

    id  descr   flag
    1   81978ceb5514461fbad9af1152ad78f6    true
    2   cc0aee68ba3e0095cc74d53e8da55fef    false
    3   689a76e5897d565638f8ddd2d2019b7a    true
    4   9df03bc2969a6af88cd1d6e0423d0f4c    true
    5   318983766d11f831e9f0df34606dc908    false
    6   198102bb71640a16f28263b7fb56ba2e    false
    7   9bef7320389db46a8ad88ffa611e81b5    false
    8   c1f0d637ee0a985aa7d768a78d2d97b1    false
    9   781b4064f721ae3879d95579264b0aba    false
    10  c4582890bb1e9af430e0f36b50f5e88c    false
    

    我需要运行的查询是:

    SELECT id
    FROM test
    WHERE flag;
    

    现在,如果我使用部分索引。查询(最终)将作为仅索引扫描执行:

    CREATE INDEX i1 
      ON test (id) WHERE flag;
    
    QUERY PLAN
    Index Only Scan using i1 on test  (cost=0.29..354.95 rows=9911 width=4) (actual time=0.120..6.268 rows=9911 loops=1)
      Heap Fetches: 9911
      Buffers: shared hit=834 read=29
    Planning time: 0.806 ms
    Execution time: 6.922 ms
    

    我不明白的是:为什么以下表单的多列索引从不用于仅索引扫描?

    CREATE INDEX i2 
      ON test (flag, id);
    
    QUERY PLAN
    Bitmap Heap Scan on test  (cost=189.10..1122.21 rows=9911 width=4) (actual time=0.767..5.986 rows=9911 loops=1)
      Filter: flag
      Heap Blocks: exact=834
      Buffers: shared hit=863
      ->  Bitmap Index Scan on i2  (cost=0.00..186.62 rows=9911 width=0) (actual time=0.669..0.669 rows=9911 loops=1)
            Index Cond: (flag = true)
            Buffers: shared hit=29
    Planning time: 0.090 ms
    Execution time: 6.677 ms
    

    查询不能访问标记为的btree的所有连续叶 True 确定所有ID?

    (请注意,元组可见性可能不是问题,因为仅索引扫描与部分索引一起使用 i1 )

    我的Postgres版本是: PostgreSQL 9.6.2 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 5.3.1-14ubuntu2) 5.3.1 20160413, 64-bit

    1 回复  |  直到 8 年前
        1
  •  1
  •   Laurenz Albe    8 年前

    VACUUM (ANALYZE) test;