Yyyl164119487IndexScan优化
4aca86c5创建于 2023年6月6日历史提交
-- Test bitmap AND and OR
-- Generate enough data that we can test the lossy bitmaps.
-- There's 55 tuples per page in the table. 53 is just
-- below 55, so that an index scan with qual a = constant
-- will return at least one hit per page. 59 is just above
-- 55, so that an index scan with qual b = constant will return
-- hits on most but not all pages. 53 and 59 are prime, so that
-- there's a maximum number of a,b combinations in the table.
-- That allows us to test all the different combinations of
-- lossy and non-lossy pages with the minimum amount of data
CREATE TABLE bmscantest (a int, b int, t text);
copy bmscantest from '@abs_srcdir@/data/bitmapops.data' DELIMITER as ',' NULL as '';
CREATE INDEX i_bmtest_a ON bmscantest(a);
CREATE INDEX i_bmtest_b ON bmscantest(b);
-- We want to use bitmapscans. With default settings, the planner currently
-- chooses a bitmap scan for the queries below anyway, but let's make sure.
set enable_indexscan=false;
set enable_seqscan=false;
-- Lower work_mem to trigger use of lossy bitmaps
set work_mem = 64;
-- Test bitmap-and.
EXPLAIN (analyze on, costs off, timing off) SELECT count(*) FROM bmscantest WHERE a = 1 AND b = 1;
                                  QUERY PLAN                                  
------------------------------------------------------------------------------
 Aggregate (actual rows=1 loops=1)
   ->  Bitmap Heap Scan on bmscantest (actual rows=20 loops=1)
         Recheck Cond: ((b = 1) AND (a = 1))
         Rows Removed by Index Recheck: 218
--?         Heap Blocks: exact=.*
         ->  BitmapAnd (actual rows=0 loops=1)
               ->  Bitmap Index Scan on i_bmtest_b (actual rows=1051 loops=1)
                     Index Cond: (b = 1)
               ->  Bitmap Index Scan on i_bmtest_a (actual rows=1170 loops=1)
                     Index Cond: (a = 1)
--?.*
(11 rows)

SELECT count(*) FROM bmscantest WHERE a = 1 AND b = 1;
 count 
-------
    20
(1 row)

-- Test bitmap-or.
EXPLAIN (analyze on, costs off, timing off) SELECT count(*) FROM bmscantest WHERE a = 1 OR b = 1;
                                  QUERY PLAN                                  
------------------------------------------------------------------------------
 Aggregate (actual rows=1 loops=1)
   ->  Bitmap Heap Scan on bmscantest (actual rows=2201 loops=1)
         Recheck Cond: ((a = 1) OR (b = 1))
         Rows Removed by Index Recheck: 16506
--?         Heap Blocks: exact=.* lossy=.*
         ->  BitmapOr (actual rows=0 loops=1)
               ->  Bitmap Index Scan on i_bmtest_a (actual rows=1170 loops=1)
                     Index Cond: (a = 1)
               ->  Bitmap Index Scan on i_bmtest_b (actual rows=1051 loops=1)
                     Index Cond: (b = 1)
--?.*
(11 rows)

SELECT count(*) FROM bmscantest WHERE a = 1 OR b = 1;
 count 
-------
  2201
(1 row)

-- clean up
DROP TABLE bmscantest;