citusdata / citusdata/citus

Issue index usage when selecting data from columnar table

Open
#7,202 3 comments 1 reaction 0 assignees View on GitHub
columnar
Dominant language
C
Stars
12.8k
Forks
794
Avg merge
2d 14h
Merged PRs (30d)
31

Description

We have huge tables (parts of partitioned table) and we need to select data from this table by equality some field. We created btree index on required field but while selecting data PostgreSQL does not use the index and performs custom or sequential scan.

It looks like there is an issue in cost estimation for select statement.

When we change next settings

```
set columnar.enable_custom_scan to off;
set enable_seqscan to off;
```

PostgreSQL starts to use index and execution time for select is much better.

See below details and reproducible test case where we see difference in 5 times for execution time. For real table that difference could be up to 10 times.

```
--
-- Versions
--
postgres=# select version();
version
-------------------------------------------------------------------------------------
PostgreSQL 12.15 on x86_64-pc-linux-gnu, compiled by gcc (SUSE Linux) 7.5.0, 64-bit
(1 row)

postgres=# select citus_version();
citus_version
---------------------------------------------------------------------------------
Citus 10.2.5 on x86_64-pc-linux-gnu, compiled by gcc (SUSE Linux) 7.5.0, 64-bit
(1 row)

--
-- Creating test table
--
postgres=# create table columnar_test(id int, data int) using columnar;
CREATE TABLE
postgres=# insert into columnar_test select generate_series(1, 100000000), (random() * 100000)::integer;
INSERT 0 100000000
postgres=# create index columnar_test_i on columnar_test using btree (data);
CREATE INDEX
postgres=# analyze columnar_test;
ANALYZE

--
-- Gathered stats
--
postgres=# select relpages, reltuples from pg_class where relname = 'columnar_test';
relpages | reltuples
----------+---------------
67970 | 2.2656667e+08
(1 row)

postgres=# select relpages, reltuples from pg_class where relname = 'columnar_test_i';
relpages | reltuples
----------+---------------
274580 | 2.2656667e+08
(1 row)

postgres=# select * from pg_stats where tablename = 'columnar_test';
-[ RECORD 1 ]----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
schemaname | pathman
tablename | columnar_test
attname | id
inherited | f
null_frac | 0
avg_width | 4
n_distinct | -1
most_common_vals |
most_common_freqs |
histogram_bounds | {1434,1097781,2048377,3045114,4021530,5127121,6083720,7130848,8174752,9132614,10197176,11146417,12224272,13193412,14260670,15159244,16285776,17315518,18235716,19278137,20269468,21297847,22300650,23371825,24348397,25243075,26157402,27152445,28137863,29126406,30194765,31320947,32355303,33309209,34274487,35370438,36406658,37334916,38303770,39217674,40183896,41254712,42235703,43276651,44311288,45308951,46181832,47207492,48319859,49329960,50428453,51381597,52444909,53386475,54316234,55254247,56290037,57348772,58378948,59396856,60414583,61413698,62333754,63447748,64410278,65418093,66447418,67427559,68398351,69393814,70381957,71332588,72206539,73266337,74317106,75303092,76219721,77211963,78161774,79070421,80058537,81045386,82106885,83176812,84102256,85060143,86052438,87061235,87983234,88894151,89972103,91019521,91935045,92987903,94023402,94919988,95972779,96911900,97907469,99010651,99999578}
correlation | 1
most_common_elems |
most_common_elem_freqs |
elem_count_histogram |
-[ RECORD 2 ]----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
schemaname | pathman
tablename | columnar_test
attname | data
inherited | f
null_frac | 0
avg_width | 4
n_distinct | 99185
most_common_vals |
most_common_freqs |
histogram_bounds | {6,1008,1896,2903,3948,4934,5889,6873,7877,8981,9948,10997,12010,12988,13978,14963,15976,17031,18093,19100,20024,21024,21932,22945,23888,24960,26028,27060,28066,29080,30128,31077,32037,33089,34156,35156,36154,37077,38108,39160,40170,41212,42177,43212,44215,45285,46245,47199,48122,49055,50166,51224,52239,53297,54276,55179,56205,57237,58276,59193,60291,61282,62400,63390,64424,65376,66410,67384,68522,69399,70460,71320,72265,73266,74446,75431,76370,77377,78304,79305,80300,81282,82237,83228,84124,85083,86063,87165,88146,89033,90031,91077,92068,93177,94151,95227,96242,97261,98173,99105,99998}
correlation | 0.00035379163
most_common_elems |
most_common_elem_freqs |
elem_count_histogram |

--
-- Selects
-- Before every select linux disk cache was cleaned (sync; echo 3 > /proc/sys/vm/drop_caches) and postgres server restarted
--

postgres=# set columnar.enable_custom_scan to on;
SET
postgres=# set enable_seqscan to on;
SET
postgres=# explain (analyze, timing, costs, buffers) select * from columnar_test where data = 42;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------
Custom Scan (ColumnarScan) on columnar_test (cost=0.00..67195.95 rows=1008 width=8) (actual time=8.107..3868.356 rows=1092 loops=1)
Filter: (data = 42)
Rows Removed by Filter: 99998908
Columnar Projected Columns: id, data
Buffers: shared hit=47333 read=68508
Planning Time: 12.226 ms
Execution Time: 3869.764 ms
(7 rows)

postgres=# set columnar.enable_custom_scan to off;
SET
postgres=# set enable_seqscan to on;
SET
postgres=# explain (analyze, timing, costs, buffers) select * from columnar_test where data = 42;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
Seq Scan on columnar_test (cost=0.00..67195.95 rows=1008 width=8) (actual time=9.041..4207.840 rows=1092 loops=1)
Filter: (data = 42)
Rows Removed by Filter: 99998908
Buffers: shared hit=47331 read=68510
Planning Time: 13.053 ms
Execution Time: 4209.209 ms
(6 rows)

postgres=# set columnar.enable_custom_scan to off;
SET
postgres=# set enable_seqscan to off;
SET
postgres=# explain (analyze, timing, costs, buffers) select * from columnar_test where data = 42;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------
Index Scan using columnar_test_i on columnar_test (cost=0.57..105569.64 rows=1008 width=8) (actual time=7.300..705.867 rows=1092 loops=1)
Index Cond: (data = 42)
Buffers: shared hit=43233 read=56486
Planning Time: 13.988 ms
Execution Time: 707.306 ms
(5 rows)

```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.