66.2. ÐÑимеÑÑ Ð¼Ð½Ð¾Ð³Ð¾Ð²Ð°ÑианÑной ÑÑаÑиÑÑики
66.2.1. ФÑнкÑионалÑнÑе завиÑимоÑÑи
ÐноговаÑианÑнÑÑ ÐºÐ¾ÑÑелÑÑÐ¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ пÑодемонÑÑÑиÑоваÑÑ Ð½Ð° оÑÐµÐ½Ñ Ð¿ÑоÑÑом набоÑе даннÑÑ â ÑаблиÑе Ñ Ð´Ð²ÑÐ¼Ñ ÑÑолбÑами, ÑодеÑжаÑими одинаковÑе знаÑениÑ:
CREATE TABLE t (a INT, b INT); INSERT INTO t SELECT i % 100, i % 100 FROM generate_series(1, 10000) s(i); ANALYZE t;
Ðак ÑаÑÑказÑваеÑÑÑ Ð² Разделе 14.2, планиÑовÑик Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð¿ÑеделиÑÑ Ð¼Ð¾ÑноÑÑÑ t, иÑÑ
Ð¾Ð´Ñ Ð¸Ð· ÑиÑла ÑÑÑÐ°Ð½Ð¸Ñ Ð¸ ÑÑÑок, полÑÑенного из pg_class:
SELECT relpages, reltuples FROM pg_class WHERE relname = 't';
relpages | reltuples
----------+-----------
45 | 10000РаÑпÑеделение даннÑÑ Ð¾ÑÐµÐ½Ñ Ð¿ÑоÑÑое: в каждом ÑÑолбÑе ÑодеÑжиÑÑÑ Ð²Ñего 100 ÑазлиÑнÑÑ Ð·Ð½Ð°Ñений, ÑавномеÑно ÑаÑпÑеделÑннÑÑ .
СледÑÑÑий пÑÐ¸Ð¼ÐµÑ Ð¿Ð¾ÐºÐ°Ð·ÑÐ²Ð°ÐµÑ ÑезÑлÑÑÐ°Ñ Ð¾ÑÐµÐ½Ð¸Ð²Ð°Ð½Ð¸Ñ ÑÑÐ»Ð¾Ð²Ð¸Ñ WHERE по ÑÑолбÑÑ a:
EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1;
QUERY PLAN
-------------------------------------------------------------------------------
Seq Scan on t (cost=0.00..170.00 rows=100 width=8) (actual rows=100 loops=1)
Filter: (a = 1)
Rows Removed by Filter: 9900 ÐланиÑовÑик ÑаÑÑмаÑÑÐ¸Ð²Ð°ÐµÑ ÑÑловие и опÑеделÑеÑ, ÑÑо его избиÑаÑелÑноÑÑÑ Ñавна 1%. СÑÐ°Ð²Ð½Ð¸Ð²Ð°Ñ ÑÑÑ Ð¾ÑÐµÐ½ÐºÑ Ð¸ ÑакÑиÑеÑкое ÑиÑло ÑÑÑок, Ð¼Ñ Ð²Ð¸Ð´Ð¸Ð¼, ÑÑо оÑенка оÑÐµÐ½Ñ ÑоÑна (на Ñамом деле абÑолÑÑна ÑоÑна, Ñак как ÑаблиÑа оÑÐµÐ½Ñ Ð¼Ð°Ð»ÐµÐ½ÑкаÑ). ÐÑли измениÑÑ ÑÑловие WHERE, ÑÑÐ¾Ð±Ñ Ð¸ÑполÑзовалÑÑ ÑÑÐ¾Ð»Ð±ÐµÑ b, бÑÐ´ÐµÑ Ð¿Ð¾Ð»ÑÑен Ñакой же план. Ðо поÑмоÑÑиÑе, ÑÑо полÑÑиÑÑÑ, еÑли Ð¼Ñ Ð¿Ñименим одинаковое ÑÑловие к двÑм ÑÑолбÑам, обÑединив иÑ
опеÑаÑоÑом AND:
EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
QUERY PLAN
-----------------------------------------------------------------------------
Seq Scan on t (cost=0.00..195.00 rows=1 width=8) (actual rows=100 loops=1)
Filter: ((a = 1) AND (b = 1))
Rows Removed by Filter: 9900ÐланиÑовÑик оÑÐµÐ½Ð¸Ð²Ð°ÐµÑ Ð¸Ð·Ð±Ð¸ÑаÑелÑноÑÑÑ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¸Ð½Ð´Ð¸Ð²Ð¸Ð´ÑалÑно, и полÑÑÐ°ÐµÑ ÑÑ Ð¶Ðµ оÑÐµÐ½ÐºÑ Ð² 1%, ÑÑо и вÑÑе. ÐаÑем он пÑедполагаеÑ, ÑÑо ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð½ÐµÐ·Ð°Ð²Ð¸ÑимÑ, Ñак ÑÑо он пеÑÐµÐ¼Ð½Ð¾Ð¶Ð°ÐµÑ Ð¸Ð·Ð±Ð¸ÑаÑелÑноÑÑи и вÑдаÑÑ Ð¾ÐºÐ¾Ð½ÑаÑелÑнÑÑ Ð¾ÑÐµÐ½ÐºÑ Ð¸Ð·Ð±Ð¸ÑаÑелÑноÑÑи, ÑавнÑÑ Ð²Ñего 0.01%. ÐÑо знаÑиÑелÑÐ½Ð°Ñ Ð½ÐµÐ´Ð¾Ð¾Ñенка, Ñак как ÑакÑиÑеÑкое ÑиÑло ÑÑÑок, ÑооÑвеÑÑÑвÑÑÑÐ¸Ñ ÑÑловиÑ, (100) на два поÑÑдка болÑÑе.
ÐÑÑ Ð¿ÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ð¼Ð¾Ð¶Ð½Ð¾ ÑеÑиÑÑ, Ñоздав обÑÐµÐºÑ ÑÑаÑиÑÑики, коÑоÑÑй ÑÐºÐ°Ð¶ÐµÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ðµ ANALYZE вÑÑиÑлиÑÑ Ð¼Ð½Ð¾Ð³Ð¾Ð²Ð°ÑианÑнÑÑ ÑÑаÑиÑÑÐ¸ÐºÑ ÑÑнкÑионалÑной завиÑимоÑÑи по двÑм ÑÑолбÑам:
CREATE STATISTICS stts (dependencies) ON a, b FROM t;
ANALYZE t;
EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1;
QUERY PLAN
-------------------------------------------------------------------------------
Seq Scan on t (cost=0.00..195.00 rows=100 width=8) (actual rows=100 loops=1)
Filter: ((a = 1) AND (b = 1))
Rows Removed by Filter: 990066.2.2. ÐноговаÑианÑное ÑиÑло ÑазлиÑнÑÑ Ð·Ð½Ð°Ñений
ÐÐ¾Ð´Ð¾Ð±Ð½Ð°Ñ Ð¿Ñоблема Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÐµÑ Ñ Ð¾Ñенкой моÑноÑÑи набоÑов Ñ Ð½ÐµÑколÑкими ÑÑолбÑами, напÑимеÑ, Ñ Ð¾Ñенкой ÑиÑла гÑÑпп, коÑоÑÑе могÑÑ Ð±ÑÑÑ Ð²ÑÐ´Ð°Ð½Ñ Ð¿Ñедложением GROUP BY. Ðогда в GROUP BY Ñказан один ÑÑолбеÑ, оÑенка ÑиÑла ÑазлиÑнÑÑ
знаÑений (коÑоÑÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ ÑвидеÑÑ ÐºÐ°Ðº ожидаемое ÑиÑло ÑÑÑок, вÑдаваемое Ñзлом HashAggregate) оÑÐµÐ½Ñ ÑоÑнаÑ:
EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a;
QUERY PLAN
-----------------------------------------------------------------------------------------
HashAggregate (cost=195.00..196.00 rows=100 width=12) (actual rows=100 loops=1)
Group Key: a
-> Seq Scan on t (cost=0.00..145.00 rows=10000 width=4) (actual rows=10000 loops=1) Ðо оÑенка ÑиÑла гÑÑпп в запÑоÑе Ñ Ð´Ð²ÑÐ¼Ñ ÑÑолбÑами в GROUP BY без многоваÑианÑной ÑÑаÑиÑÑики, как и в пÑедÑдÑÑем пÑимеÑе, оÑлиÑаеÑÑÑ Ð¾Ñ Ð¿ÑавилÑной на поÑÑдок:
EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
QUERY PLAN
--------------------------------------------------------------------------------------------
HashAggregate (cost=220.00..230.00 rows=1000 width=16) (actual rows=100 loops=1)
Group Key: a, b
-> Seq Scan on t (cost=0.00..145.00 rows=10000 width=8) (actual rows=10000 loops=1)ÐÑли пеÑеопÑеделиÑÑ Ð¾Ð±ÑÐµÐºÑ ÑÑаÑиÑÑики, ÑÑÐ¾Ð±Ñ Ð¾Ð½ вклÑÑал подÑÑÑÑ ÑиÑла ÑазлиÑнÑÑ Ð·Ð½Ð°Ñений Ð´Ð»Ñ Ð´Ð²ÑÑ ÑÑолбÑов, оÑенка ÑÑÐ°Ð½ÐµÑ Ð³Ð¾Ñаздо лÑÑÑе:
DROP STATISTICS stts;
CREATE STATISTICS stts (dependencies, ndistinct) ON a, b FROM t;
ANALYZE t;
EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a, b;
QUERY PLAN
--------------------------------------------------------------------------------------------
HashAggregate (cost=220.00..221.00 rows=100 width=16) (actual rows=100 loops=1)
Group Key: a, b
-> Seq Scan on t (cost=0.00..145.00 rows=10000 width=8) (actual rows=10000 loops=1)