
База данных и таблица
~~~~~~~~~~~~~~~~~~~~~


=> create database db17;
CREATE DATABASE

=> \c db17
You are now connected to database "db17" as user "postgres".

=> create table t(id serial primary key, flag boolean)
=> with (autovacuum_enabled = off);
CREATE TABLE

Вставка строк
~~~~~~~~~~~~~


=> insert into t(flag) select mod(gen.id,100)=0 from generate_series(1,10000) as gen(id);
INSERT 0 10000

Статистики нет:

=> select reltuples from pg_class where oid = 't'::regclass;
 reltuples 
-----------
         0
(1 row)


=> select count(*) from pg_stats where tablename = 't';
 count 
-------
     0
(1 row)


Планы запросов
~~~~~~~~~~~~~~


=> explain select * from t;
                      QUERY PLAN                       
-------------------------------------------------------
 Seq Scan on t  (cost=0.00..156.15 rows=11115 width=5)
(1 row)


Даже без статистики оптимизатору удалось примерно угадать число строк -
за счет знания размера файла и ширины полей.

=> explain select * from t where flag;
                      QUERY PLAN                      
------------------------------------------------------
 Seq Scan on t  (cost=0.00..156.15 rows=5558 width=5)
   Filter: flag
(2 rows)


Селективность условия оценена как 1/2, поскольку тип предполагает 2 значения.

=> explain select * from t where id <= 200;
                               QUERY PLAN                                
-------------------------------------------------------------------------
 Bitmap Heap Scan on t  (cost=61.00..152.31 rows=3705 width=5)
   Recheck Cond: (id <= 200)
   ->  Bitmap Index Scan on t_pkey  (cost=0.00..60.07 rows=3705 width=0)
         Index Cond: (id <= 200)
(4 rows)


Здесь селективность оценена как 1/3. Это просто константа, любое другое условие
неравенства будет от безысходности оценено точно так же:

=> explain select * from t where id <= 42;
                               QUERY PLAN                                
-------------------------------------------------------------------------
 Bitmap Heap Scan on t  (cost=61.00..152.31 rows=3705 width=5)
   Recheck Cond: (id <= 42)
   ->  Bitmap Index Scan on t_pkey  (cost=0.00..60.07 rows=3705 width=0)
         Index Cond: (id <= 42)
(4 rows)


Анализ таблицы
~~~~~~~~~~~~~~


=> analyze t;
ANALYZE

=> select reltuples from pg_class where oid = 't'::regclass;
 reltuples 
-----------
     10000
(1 row)


=> \x
Expanded display is on.

=> select attname, null_frac, n_distinct, most_common_vals, most_common_freqs, histogram_bounds, correlation from pg_stats where tablename = 't' and attname = 'id';
-[ RECORD 1 ]-----+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
attname           | id
null_frac         | 0
n_distinct        | -1
most_common_vals  | 
most_common_freqs | 
histogram_bounds  | {1,100,200,300,400,500,600,700,800,900,1000,1100,1200,1300,1400,1500,1600,1700,1800,1900,2000,2100,2200,2300,2400,2500,2600,2700,2800,2900,3000,3100,3200,3300,3400,3500,3600,3700,3800,3900,4000,4100,4200,4300,4400,4500,4600,4700,4800,4900,5000,5100,5200,5300,5400,5500,5600,5700,5800,5900,6000,6100,6200,6300,6400,6500,6600,6700,6800,6900,7000,7100,7200,7300,7400,7500,7600,7700,7800,7900,8000,8100,8200,8300,8400,8500,8600,8700,8800,8900,9000,9100,9200,9300,9400,9500,9600,9700,9800,9900,10000}
correlation       | 1


Здесь число уникальных значение представлено долей: единица означает 100%,
то есть все значения уникальны вне зависимости от размера таблицы.
Списка частых значений нет (все значения имеют одинаковую частоту).

=> select attname, null_frac, n_distinct, most_common_vals, most_common_freqs, histogram_bounds, correlation from pg_stats where tablename = 't' and attname = 'flag';
-[ RECORD 1 ]-----+------------
attname           | flag
null_frac         | 0
n_distinct        | 2
most_common_vals  | {f,t}
most_common_freqs | {0.99,0.01}
histogram_bounds  | 
correlation       | 0.980496


Здесь наоборот, есть список частых значений. Поскольку их всего два,
в гистограмме нет смысла.

=> \x
Expanded display is off.

Планы запросов
~~~~~~~~~~~~~~


=> explain select * from t;
                      QUERY PLAN                       
-------------------------------------------------------
 Seq Scan on t  (cost=0.00..145.00 rows=10000 width=5)
(1 row)


Оценка исправилась (reltuples).

=> explain select * from t where flag;
                     QUERY PLAN                      
-----------------------------------------------------
 Seq Scan on t  (cost=0.00..145.00 rows=100 width=5)
   Filter: flag
(2 rows)


Селективность условия оценена как 0.01 - это число из most_common_freqs
для значения t.

=> explain select * from t where id <= 200;
                            QUERY PLAN                             
-------------------------------------------------------------------
 Index Scan using t_pkey on t  (cost=0.29..11.79 rows=200 width=5)
   Index Cond: (id <= 200)
(2 rows)


Селективность оценена исходя из гистограммы - под условие попадает ровно две
корзины, отсюда 2/100, где 100 - число корзин.

=> \q
