67.1. ÐÑимеÑÑ Ð¾Ñенки колиÑеÑÑва ÑÑÑок
РпÑиведÑннÑÑ
ниже пÑимеÑаÑ
иÑполÑзÑÑÑÑÑ ÑаблиÑÑ Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ
ÑегÑеÑÑионного ÑеÑÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Postgres Pro. ÐÑиведÑннÑе лиÑÑинги полÑÑÐµÐ½Ñ Ð² веÑÑии 8.3. Ðоведение более ÑанниÑ
(или поздниÑ
) веÑÑий Ð¼Ð¾Ð¶ÐµÑ Ð¾ÑлиÑаÑÑÑÑ. ÐамеÑÑÑе Ñакже, ÑÑо поÑколÑÐºÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° ANALYZE иÑполÑзÑÐµÑ ÑлÑÑайнÑÑ Ð²ÑбоÑÐºÑ Ð¿Ñи ÑоÑмиÑовании ÑÑаÑиÑÑики, поÑле лÑбого нового вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ ANALYZE ÑезÑлÑÑаÑÑ Ð½ÐµÐ·Ð½Ð°ÑиÑелÑно изменÑÑÑÑ.
ÐавайÑе наÑнÑм Ñ Ð¾ÑÐµÐ½Ñ Ð¿ÑоÑÑого запÑоÑа:
EXPLAIN SELECT * FROM tenk1;
QUERY PLAN
-------------------------------------------------------------
Seq Scan on tenk1 (cost=0.00..458.00 rows=10000 width=244) Ðак планиÑовÑик опÑеделÑÐµÑ Ð¼Ð¾ÑноÑÑÑ tenk1, ÑаÑÑмаÑÑиваеÑÑÑ Ð²ÑÑе (Ñм. Раздел 14.2), но Ð´Ð»Ñ Ð¿Ð¾Ð»Ð½Ð¾ÑÑ Ð·Ð´ÐµÑÑ Ð³Ð¾Ð²Ð¾ÑиÑÑÑ Ð¾Ð± ÑÑом еÑÑ Ñаз. ÐолиÑеÑÑво ÑÑÑÐ°Ð½Ð¸Ñ Ð¸ ÑÑÑок беÑÑÑÑÑ Ð² pg_class:
SELECT relpages, reltuples FROM pg_class WHERE relname = 'tenk1';
relpages | reltuples
----------+-----------
358 | 10000ÐÑо ÑекÑÑие ÑиÑÑÑ, полÑÑеннÑе пÑи поÑледнем вÑполнении команд VACUUM или ANALYZE, пÑименÑннÑÑ
к ÑÑой ÑаблиÑе. ÐаÑем планиÑовÑик вÑполнÑÐµÑ Ð²ÑбоÑÐºÑ ÑакÑиÑеÑкого ÑекÑÑего ÑиÑла ÑÑÑÐ°Ð½Ð¸Ñ Ð² ÑаблиÑе (ÑÑо недоÑÐ¾Ð³Ð°Ñ Ð¾Ð¿ÐµÑаÑиÑ, Ð´Ð»Ñ ÐºÐ¾ÑоÑой не ÑÑебÑеÑÑÑ ÑканиÑование ÑаблиÑÑ). ÐÑли оно оÑлиÑаеÑÑÑ Ð¾Ñ relpages, Ñо reltuples изменÑеÑÑÑ Ð´Ð»Ñ Ñого, ÑÑÐ¾Ð±Ñ Ð¿ÑивеÑÑи ÑÑо знаÑение к ÑекÑÑей оÑенке колиÑеÑÑва ÑÑÑок. Рпоказанном вÑÑе пÑимеÑе знаÑение relpages ÑвлÑеÑÑÑ Ð°ÐºÑÑалÑнÑм, поÑÑÐ¾Ð¼Ñ ÐºÐ¾Ð»Ð¸ÑеÑÑво ÑÑÑок беÑÑÑÑÑ ÑавнÑм reltuples.
ÐавайÑе обÑаÑимÑÑ Ðº пÑимеÑÑ Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð½Ñм ÑÑловием в пÑедложении WHERE:
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 1000;
QUERY PLAN
-------------------------------------------------------------------â-------------
Bitmap Heap Scan on tenk1 (cost=24.06..394.64 rows=1007 width=244)
Recheck Cond: (unique1 < 1000)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..23.80 rows=1007 width=0)
Index Cond: (unique1 < 1000) ÐланиÑовÑик ÑаÑÑмаÑÑÐ¸Ð²Ð°ÐµÑ ÑÑловие пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ WHERE и наÑ
Ð¾Ð´Ð¸Ñ Ð² ÑпÑавоÑнике ÑÑнкÑÐ¸Ñ Ð¸Ð·Ð±Ð¸ÑаÑелÑноÑÑи Ð´Ð»Ñ Ð¾Ð¿ÐµÑаÑоÑа < в pg_operator. ÐÑо знаÑение ÑодеÑжиÑÑÑ Ð² ÑÑолбÑе oprrest, и в данном ÑлÑÑае знаÑением ÑвлÑеÑÑÑ scalarltsel. ФÑнкÑÐ¸Ñ scalarltsel Ð¸Ð·Ð²Ð»ÐµÐºÐ°ÐµÑ Ð³Ð¸ÑÑогÑÐ°Ð¼Ð¼Ñ Ð´Ð»Ñ unique1 из pg_statistic. ÐÐ»Ñ Ð²Ð²Ð¾Ð´Ð¸Ð¼ÑÑ
вÑÑÑнÑÑ Ð·Ð°Ð¿ÑоÑов Ñдобнее пÑоÑмаÑÑиваÑÑ Ð±Ð¾Ð»ÐµÐµ пÑоÑÑое пÑедÑÑавление pg_stats:
SELECT histogram_bounds FROM pg_stats
WHERE tablename='tenk1' AND attname='unique1';
histogram_bounds
------------------------------------------------------
{0,993,1997,3050,4040,5036,5957,7057,8029,9016,9995}ÐаÑем обÑабаÑÑваеÑÑÑ ÑаÑÑÑ Ð³Ð¸ÑÑогÑаммÑ, коÑоÑÐ°Ñ ÑооÑвеÑÑÑвÑÐµÑ ÑÑÐ»Ð¾Ð²Ð¸Ñ Â«< 1000». Таким обÑазом и опÑеделÑеÑÑÑ Ð¸Ð·Ð±Ð¸ÑаÑелÑноÑÑÑ. ÐиÑÑогÑамма Ð´ÐµÐ»Ð¸Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½ на ÑавнÑе ÑаÑÑоÑнÑе гÑÑппÑ, поÑÑÐ¾Ð¼Ñ Ð½Ñжно лиÑÑ Ð¾Ð¿ÑеделиÑÑ Ð³ÑÑппÑ, ÑодеÑжаÑÑÑ Ð½Ð°Ñе знаÑение, и подÑÑиÑаÑÑ ÐµÑ Ð´Ð¾Ð»Ñ Ð¸ Ð´Ð¾Ð»Ñ Ð³ÑÑпп, пÑедÑеÑÑвÑÑÑÐ¸Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹. ÐÑевидно, ÑÑо знаÑение 1000 Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ Ð²Ð¾ вÑоÑой гÑÑппе (993â1997). ÐÑли пÑедположиÑÑ, ÑÑо внÑÑÑи каждой гÑÑÐ¿Ð¿Ñ ÑаÑпÑеделение знаÑений линейное, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ вÑÑиÑлиÑÑ Ð¸Ð·Ð±Ð¸ÑаÑелÑноÑÑÑ ÑледÑÑÑим обÑазом:
selectivity = (1 + (1000 - bucket[2].min)/(bucket[2].max - bucket[2].min))/num_buckets
= (1 + (1000 - 993)/(1997 - 993))/10
= 0.100697 Ñ. е. ÑÑмма ÑлеменÑов одной Ñелой гÑÑÐ¿Ð¿Ñ Ð¸ пÑопоÑÑионалÑной ÑаÑÑи ÑлеменÑов вÑоÑой, делÑÐ½Ð½Ð°Ñ Ð½Ð° ÑиÑло гÑÑпп. ТепеÑÑ Ð¿ÑимеÑное ÑиÑло ÑÑÑок Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑаÑÑÑиÑано как пÑоизведение избиÑаÑелÑноÑÑи и моÑноÑÑи tenk1:
rows = rel_cardinality * selectivity
= 10000 * 0.100697
= 1007 (окÑÑглÑнно)Ðалее, давайÑе ÑаÑÑмоÑÑим пÑÐ¸Ð¼ÐµÑ Ñ ÑÑловием на ÑавенÑÑво в пÑедложении WHERE:
EXPLAIN SELECT * FROM tenk1 WHERE stringu1 = 'CRAAAA';
QUERY PLAN
----------------------------------------------------------
Seq Scan on tenk1 (cost=0.00..483.00 rows=30 width=244)
Filter: (stringu1 = 'CRAAAA'::name) ÐланиÑовÑик Ð²Ð½Ð¾Ð²Ñ Ð¿ÑовеÑÑÐµÑ ÑÑловие в пÑедложении WHERE и опÑеделÑÐµÑ ÑÑнкÑÐ¸Ñ Ð¸Ð·Ð±Ð¸ÑаÑелÑноÑÑи Ð´Ð»Ñ =, и ÑÑой ÑÑнкÑией ÑвлÑеÑÑÑ eqsel. ÐÐ»Ñ Ð¾Ñенки ÑавенÑÑва гиÑÑогÑамма беÑполезна, вмеÑÑо Ð½ÐµÑ Ð´Ð»Ñ Ð¾Ñенки избиÑаÑелÑноÑÑи иÑполÑзÑеÑÑÑ ÑпиÑок ÑамÑÑ
ÑаÑÑÑÑ
знаÑений (Most Common Values, MCV). ÐавайÑе ÑаÑÑмоÑÑим MCV и ÑооÑвеÑÑÑвÑÑÑие дополниÑелÑнÑе ÑÑолбÑÑ, коÑоÑÑе пÑигодÑÑÑÑ Ð¿Ð¾Ð·Ð¶Ðµ:
SELECT null_frac, n_distinct, most_common_vals, most_common_freqs FROM pg_stats
WHERE tablename='tenk1' AND attname='stringu1';
null_frac | 0
n_distinct | 676
most_common_vals | {EJAAAA,BBAAAA,CRAAAA,FCAAAA,FEAAAA,GSAAAA,âJOAAAA,MCAAAA,NAAAAA,WGAAAA}
most_common_freqs | {0.00333333,0.003,0.003,0.003,0.003,0.003,â0.003,0.003,0.003,0.003} Так как знаÑение CRAAAA оказалоÑÑ Ð² ÑпиÑке MCV, избиÑаÑелÑноÑÑÑ Ð±ÑÐ´ÐµÑ Ð¾Ð¿ÑеделÑÑÑÑÑ Ð¿ÑоÑÑо ÑооÑвеÑÑÑвÑÑÑим ÑлеменÑом в ÑпиÑке ÑаÑÑÐ¾Ñ ÑамÑÑ
ÑаÑÑÑÑ
знаÑений (Most Common Frequencies, MCF):
selectivity = mcf[3]
= 0.003 Ðак и в пÑедÑдÑÑем пÑимеÑе, оÑенка ÑиÑла ÑÑÑок беÑÑÑÑÑ ÐºÐ°Ðº пÑоизведение моÑноÑÑи и избиÑаÑелÑноÑÑи tenk1:
rows = 10000 * 0.003
= 30ТепеÑÑ ÑаÑÑмоÑÑим ÑÐ¾Ñ Ð¶Ðµ ÑамÑй запÑоÑ, но Ñ ÐºÐ¾Ð½ÑÑанÑой, коÑоÑой Ð½ÐµÑ Ð² ÑпиÑке MCV:
EXPLAIN SELECT * FROM tenk1 WHERE stringu1 = 'xxx';
QUERY PLAN
----------------------------------------------------------
Seq Scan on tenk1 (cost=0.00..483.00 rows=15 width=244)
Filter: (stringu1 = 'xxx'::name)ÐÑо ÑовеÑÑенно дÑÑÐ³Ð°Ñ Ð·Ð°Ð´Ð°Ñа â как оÑениÑÑ Ð¸Ð·Ð±Ð¸ÑаÑелÑноÑÑÑ Ð·Ð½Ð°ÑениÑ, коÑоÑого Ð½ÐµÑ Ð² ÑпиÑке MCV. ÐÑи ÐµÑ ÑеÑении иÑполÑзÑеÑÑÑ ÑÐ°ÐºÑ Ð¾ÑÑÑÑÑÑÐ²Ð¸Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ знаÑÐµÐ½Ð¸Ñ Ð² ÑпиÑке в ÑоÑеÑании Ñ ÑаÑÑоÑой Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ знаÑÐµÐ½Ð¸Ñ Ð¸Ð· ÑпиÑка MCV.
selectivity = (1 - sum(mvf))/(num_distinct - num_mcv)
= (1 - (0.00333333 + 0.003 + 0.003 + 0.003 + 0.003 + 0.003 +
0.003 + 0.003 + 0.003 + 0.003))/(676 - 10)
= 0.0014559Т. е. нÑжно ÑложиÑÑ ÑаÑÑоÑÑ Ð·Ð½Ð°Ñений из ÑпиÑка MCV, оÑнÑÑÑ Ð¿Ð¾Ð»ÑÑенное ÑиÑло Ð¾Ñ ÐµÐ´Ð¸Ð½Ð¸ÑÑ, и полÑÑенное знаÑение ÑазделиÑÑ Ð½Ð° колиÑеÑÑво оÑÑалÑнÑÑ ÑникалÑнÑÑ Ð·Ð½Ð°Ñений. ÐÑи вÑÑиÑÐ»ÐµÐ½Ð¸Ñ Ð¾ÑÐ½Ð¾Ð²Ð°Ð½Ñ Ð½Ð° пÑедположении, ÑÑо знаÑениÑ, коÑоÑÑе не Ð²Ñ Ð¾Ð´ÑÑ Ð² ÑпиÑок MCV, имеÑÑ ÑавномеÑное ÑаÑпÑеделение. ÐамеÑÑÑе, ÑÑо в данном пÑимеÑе Ð½ÐµÑ Ð½ÐµÐ¾Ð¿ÑеделÑннÑÑ Ð·Ð½Ð°Ñений, поÑÑÐ¾Ð¼Ñ Ð¾ Ð½Ð¸Ñ Ð±ÐµÑпокоиÑÑÑÑ Ð½Ðµ нÑжно (инаÑе Ð¸Ñ Ð´Ð¾Ð»Ñ Ñакже пÑиÑлоÑÑ Ð±Ñ Ð²ÑÑиÑаÑÑ Ð¸Ð· ÑиÑлиÑелÑ). ÐÑенка ÑиÑла ÑÑÑок заÑем пÑоизводиÑÑÑ ÐºÐ°Ðº обÑÑно:
rows = 10000 * 0.0014559
= 15 (окÑÑглÑнно)ÐÑедÑдÑÑий пÑÐ¸Ð¼ÐµÑ Ñ unique1 < 1000 бÑл болÑÑим ÑпÑоÑением Ñого, ÑÑо в дейÑÑвиÑелÑноÑÑи Ð´ÐµÐ»Ð°ÐµÑ scalarltsel. Ðо поÑле Ñого, как Ð¼Ñ Ñвидели пÑÐ¸Ð¼ÐµÑ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑпиÑка MCV, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ внеÑÑи некоÑоÑÑе дополнениÑ. ЧÑо каÑаеÑÑÑ Ñамого пÑимеÑа, в нÑм вÑе бÑло пÑавилÑно, поÑколÑÐºÑ unique1 â ÑÑо ÑникалÑнÑй ÑÑолбеÑ, Ñ Ð½ÐµÐ³Ð¾ Ð½ÐµÑ Ð·Ð½Ð°Ñений в ÑпиÑке MCV (оÑевидно, в данном ÑлÑÑае Ð½ÐµÑ Ð·Ð½Ð°ÑениÑ, коÑоÑое вÑÑÑеÑаеÑÑÑ ÑаÑе, Ñем какое-либо дÑÑгое). ÐÐ»Ñ Ð½ÐµÑникалÑного ÑÑолбÑа обÑÑно ÑоздаÑÑÑÑ ÐºÐ°Ðº гиÑÑогÑамма, Ñак и ÑпиÑок MCV, пÑи ÑÑом гиÑÑогÑамма не вклÑÑÐ°ÐµÑ Ð·Ð½Ð°ÑениÑ, пÑедÑÑавленнÑе в ÑпиÑке MCV. ÐаннÑй ÑпоÑоб позволÑÐµÑ Ð²ÑполниÑÑ Ð±Ð¾Ð»ÐµÐµ ÑоÑнÑй подÑÑÑÑ. Ð ÑÑой ÑиÑÑаÑии scalarltsel напÑÑмÑÑ Ð¿ÑименÑÐµÑ ÑÑловие «< 1000» к ÐºÐ°Ð¶Ð´Ð¾Ð¼Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ ÑпиÑка MCV и ÑÑммиÑÑÐµÑ ÑаÑÑоÑÑ Ð·Ð½Ð°Ñений MCV, Ð´Ð»Ñ ÐºÐ¾ÑоÑÑÑ
ÑÑловие ÑвлÑеÑÑÑ Ð²ÐµÑнÑм. ÐÑо даÑÑ ÑоÑнÑÑ Ð¾ÑÐµÐ½ÐºÑ Ð¸Ð·Ð±Ð¸ÑаÑелÑноÑÑи Ð´Ð»Ñ Ñой ÑаÑÑи ÑаблиÑÑ, коÑоÑÐ°Ñ ÑодеÑÐ¶Ð¸Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¸Ð· ÑпиÑка MCV. ÐодобнÑм же обÑазом иÑполÑзÑеÑÑÑ Ð³Ð¸ÑÑогÑамма Ð´Ð»Ñ Ð¾Ñенки избиÑаÑелÑноÑÑи Ð´Ð»Ñ Ñой ÑаÑÑи ÑаблиÑÑ, коÑоÑÐ°Ñ Ð½Ðµ ÑодеÑÐ¶Ð¸Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¸Ð· ÑпиÑка MCV, а заÑем ÑÑи две ÑиÑÑÑ ÑкладÑваÑÑÑÑ Ð´Ð»Ñ Ð¾Ñенки обÑей избиÑаÑелÑноÑÑи. ÐапÑимеÑ, ÑаÑÑмоÑÑим
EXPLAIN SELECT * FROM tenk1 WHERE stringu1 < 'IAAAAA';
QUERY PLAN
------------------------------------------------------------
Seq Scan on tenk1 (cost=0.00..483.00 rows=3077 width=244)
Filter: (stringu1 < 'IAAAAA'::name) ÐÑ Ñже видели даннÑе ÑпиÑка MCV Ð´Ð»Ñ stringu1, а ÑÑо его гиÑÑогÑамма:
SELECT histogram_bounds FROM pg_stats
WHERE tablename='tenk1' AND attname='stringu1';
histogram_bounds
-------------------------------------------------------------------â-------------
{AAAAAA,CQAAAA,FRAAAA,IBAAAA,KRAAAA,NFAAAA,PSAAAA,SGAAAA,VAAAAA,âXLAAAA,ZZAAAA} ÐÑовеÑÑÑ ÑпиÑок MCV, наÑ
одим, ÑÑо ÑÑловие stringu1 < 'IAAAAA' ÑооÑвеÑÑÑвÑÐµÑ Ð¿ÐµÑвÑм ÑеÑÑи запиÑÑм, но не ÑооÑвеÑÑÑвÑÐµÑ Ð¿Ð¾Ñледним ÑеÑÑÑÑм, поÑÑÐ¾Ð¼Ñ Ð¸Ð·Ð±Ð¸ÑаÑелÑноÑÑÑ Ð´Ð»Ñ Ð·Ð½Ð°Ñений, ÑооÑвеÑÑÑвÑÑÑиÑ
знаÑениÑм в ÑпиÑке MCV, Ñакова:
selectivity = sum(relevant mvfs)
= 0.00333333 + 0.003 + 0.003 + 0.003 + 0.003 + 0.003
= 0.01833333 СÑмма вÑеÑ
ÑаÑÑÐ¾Ñ Ð¸Ð· ÑпиÑка MCF Ñакже ÑообÑÐ°ÐµÑ Ð½Ð°Ð¼, ÑÑо обÑÐ°Ñ ÑаÑÑÑ Ð¿ÑедÑÑавленной ÑпиÑком MCV ÑовокÑпноÑÑи запиÑей ÑавнÑеÑÑÑ 0.03033333, и поÑÑÐ¾Ð¼Ñ Ð¿ÑедÑÑÐ°Ð²Ð»ÐµÐ½Ð½Ð°Ñ Ð³Ð¸ÑÑогÑаммой ÑаÑÑÑ ÑавнÑеÑÑÑ 0.96966667 (в ÑÑом ÑлÑÑае Ñоже Ð½ÐµÑ Ð½ÐµÐ¾Ð¿ÑеделÑннÑÑ
знаÑений, инаÑе иÑ
пÑиÑлоÑÑ Ð±Ñ Ñакже иÑклÑÑиÑÑ). Ðидно, ÑÑо знаÑение IAAAAA Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ Ð¿Ð¾ÑÑи в ÐºÐ¾Ð½ÐµÑ ÑÑеÑÑего ÑÑолбÑа гиÑÑогÑаммÑ. ÐÑновÑваÑÑÑ Ð½Ð° пÑоÑÑÑÑ
пÑедположениÑÑ
оÑноÑиÑелÑно ÑаÑÑоÑÑ ÑазлиÑнÑÑ
Ñимволов, планиÑовÑик полÑÑÐ°ÐµÑ ÑиÑло 0.298387 Ð´Ð»Ñ ÑаÑÑи знаÑений, пÑедÑÑавленнÑÑ
в гиÑÑогÑамме, коÑоÑÑе менÑÑе Ñем IAAAAA. ÐаÑем обÑединÑем оÑенки ÑаÑÑи знаÑений из ÑпиÑка MCV и знаÑений, не ÑодеÑжаÑиÑ
ÑÑ Ð² нÑм:
selectivity = mcv_selectivity + histogram_selectivity * histogram_fraction
= 0.01833333 + 0.298387 * 0.96966667
= 0.307669
rows = 10000 * 0.307669
= 3077 (окÑÑглÑнно)Ð ÑÑом конкÑеÑном пÑимеÑе, коÑÑекÑиÑовка Ñо ÑÑоÑÐ¾Ð½Ñ ÑпиÑка MCV доÑÑаÑоÑно мала, поÑÐ¾Ð¼Ñ ÑÑо ÑаÑпÑеделение знаÑений ÑÑолбÑа доволÑно плоÑкое (ÑÑаÑиÑÑика, показÑваÑÑÐ°Ñ ÐºÐ¾Ð½ÐºÑеÑнÑе знаÑÐµÐ½Ð¸Ñ ÐºÐ°Ðº более ÑаÑпÑоÑÑÑанÑннÑе, ÑаÑе вÑего полÑÑаеÑÑÑ Ð²ÑледÑÑвие ÑÑаÑиÑÑиÑеÑкой погÑеÑноÑÑи). Рболее ÑипиÑном ÑлÑÑае, когда некоÑоÑÑе знаÑÐµÐ½Ð¸Ñ ÑвлÑÑÑÑÑ Ð·Ð½Ð°ÑиÑелÑно более ÑаÑпÑоÑÑÑанÑннÑми по ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ñ Ð´ÑÑгими, ÑÑÐ¾Ñ Ð±Ð¾Ð»ÐµÐµ ÑложнÑй меÑод повÑÑÐ°ÐµÑ ÑоÑноÑÑÑ Ð²ÑледÑÑвие ÑоÑного опÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¸Ð·Ð±Ð¸ÑаÑелÑноÑÑи наиболее ÑаÑпÑоÑÑÑанÑннÑÑ Ð·Ð½Ð°Ñений.
ТепеÑÑ Ð´Ð°Ð²Ð°Ð¹Ñе ÑаÑÑмоÑÑим ÑлÑÑай Ñ Ð±Ð¾Ð»ÐµÐµ Ñем одним ÑÑловием в пÑедложении WHERE:
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 1000 AND stringu1 = 'xxx';
QUERY PLAN
-------------------------------------------------------------------â-------------
Bitmap Heap Scan on tenk1 (cost=23.80..396.91 rows=1 width=244)
Recheck Cond: (unique1 < 1000)
Filter: (stringu1 = 'xxx'::name)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..23.80 rows=1007 width=0)
Index Cond: (unique1 < 1000)ÐланиÑовÑик иÑÑ Ð¾Ð´Ð¸Ñ Ð¸Ð· Ñого, ÑÑо два ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð½ÐµÐ·Ð°Ð²Ð¸ÑимÑ, Ñаким обÑазом, оÑделÑнÑе знаÑÐµÐ½Ð¸Ñ Ð¸Ð·Ð±Ð¸ÑаÑелÑноÑÑи можно пеÑемножиÑÑ:
selectivity = selectivity(unique1 < 1000) * selectivity(stringu1 = 'xxx')
= 0.100697 * 0.0014559
= 0.0001466
rows = 10000 * 0.0001466
= 1 (окÑÑглÑнно)ÐамеÑÑÑе, ÑÑо ÑиÑло ÑÑÑок, коÑоÑÑе пÑедполагаеÑÑÑ Ð²ÐµÑнÑÑÑ ÑеÑез ÑканиÑование биÑового индекÑа, ÑооÑвеÑÑÑвÑÐµÑ ÑÑловиÑ, иÑполÑзÑÐµÐ¼Ð¾Ð¼Ñ Ð¿Ñи ÑабоÑе индекÑа; ÑÑо важно, Ñак как влиÑÐµÑ Ð½Ð° оÑÐµÐ½ÐºÑ ÑÑоимоÑÑи Ð´Ð»Ñ Ð¿Ð¾ÑледÑÑÑÐ¸Ñ Ð²ÑбоÑок из ÑаблиÑÑ.
РзаклÑÑение иÑÑледÑем запÑоÑ, вÑполнÑÑÑий Ñоединение:
EXPLAIN SELECT * FROM tenk1 t1, tenk2 t2
WHERE t1.unique1 < 50 AND t1.unique2 = t2.unique2;
QUERY PLAN
-------------------------------------------------------------------â-------------------
Nested Loop (cost=4.64..456.23 rows=50 width=488)
-> Bitmap Heap Scan on tenk1 t1 (cost=4.64..142.17 rows=50 width=244)
Recheck Cond: (unique1 < 50)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.63 rows=50 width=0)
Index Cond: (unique1 < 50)
-> Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.00..6.27 rows=1 width=244)
Index Cond: (unique2 = t1.unique2) ÐгÑаниÑение, накладÑваемое на tenk1, unique1 < 50, пÑоизводиÑÑÑ Ð´Ð¾ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½Ñм Ñиклом. ÐÑо обÑабаÑÑваеÑÑÑ Ð°Ð½Ð°Ð»Ð¾Ð³Ð¸Ñно пÑедÑдÑÑÐµÐ¼Ñ Ð¿ÑимеÑÑ Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð½Ñм ÑÑловием. Ðа ÑÑÐ¾Ñ Ñаз знаÑение 50 Ð¿Ð¾Ð¿Ð°Ð´Ð°ÐµÑ Ð² пеÑвÑй ÑÑÐ¾Ð»Ð±ÐµÑ Ð³Ð¸ÑÑогÑÐ°Ð¼Ð¼Ñ unique1:
selectivity = (0 + (50 - bucket[1].min)/(bucket[1].max - bucket[1].min))/num_buckets
= (0 + (50 - 0)/(993 - 0))/10
= 0.005035
rows = 10000 * 0.005035
= 50 (окÑÑглÑнно) ÐгÑаниÑение Ð´Ð»Ñ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ ÑледÑÑÑее t2.unique2 = t1.unique2. ÐдеÑÑ Ð¸ÑполÑзÑеÑÑÑ Ñже извеÑÑнÑй нам опеÑаÑÐ¾Ñ =, однако ÑÑнкÑÐ¸Ñ Ð¸Ð·Ð±Ð¸ÑаÑелÑноÑÑи полÑÑаем из ÑÑолбÑа oprjoin пÑедÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ pg_operator, и ÑÑа ÑÑнкÑÐ¸Ñ â eqjoinsel. ФÑнкÑÐ¸Ñ eqjoinsel наÑ
Ð¾Ð´Ð¸Ñ ÑÑаÑиÑÑиÑеÑкие даннÑе как Ð´Ð»Ñ tenk2, Ñак и Ð´Ð»Ñ tenk1:
SELECT tablename, null_frac,n_distinct, most_common_vals FROM pg_stats
WHERE tablename IN ('tenk1', 'tenk2') AND attname='unique2';
tablename | null_frac | n_distinct | most_common_vals
-----------+-----------+------------+------------------
tenk1 | 0 | -1 |
tenk2 | 0 | -1 | Ð ÑÑом ÑлÑÑае Ð½ÐµÑ Ð´Ð°Ð½Ð½ÑÑ
MCV Ð´Ð»Ñ unique2, поÑÐ¾Ð¼Ñ ÑÑо вÑе знаÑÐµÐ½Ð¸Ñ Ð±ÑдÑÑ ÑникалÑнÑми. Таким обÑазом, иÑполÑзÑеÑÑÑ Ð°Ð»Ð³Ð¾ÑиÑм, завиÑÑÑий ÑолÑко Ð¾Ñ ÑиÑла ÑазлиÑаÑÑиÑ
ÑÑ Ð·Ð½Ð°Ñений Ð´Ð»Ñ Ð¾Ð±ÐµÐ¸Ñ
ÑÐ°Ð±Ð»Ð¸Ñ Ð¸ Ð¾Ñ Ð´Ð°Ð½Ð½ÑÑ
Ñ Ð½ÐµÐ¾Ð¿ÑеделÑннÑми знаÑениÑми:
selectivity = (1 - null_frac1) * (1 - null_frac2) * min(1/num_distinct1, 1/num_distinct2)
= (1 - 0) * (1 - 0) / max(10000, 10000)
= 0.0001То еÑÑÑ Ð²ÑÑиÑаем Ð´Ð¾Ð»Ñ Ð½ÐµÐ¾Ð¿ÑеделÑннÑÑ Ð·Ð½Ð°Ñений из единиÑÑ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑаблиÑÑ Ð¸ делим на макÑималÑное из ÑиÑел ÑазлиÑаÑÑÐ¸Ñ ÑÑ Ð·Ð½Ð°Ñений. ÐолиÑеÑÑво ÑÑÑок, коÑоÑое Ñоединение, веÑоÑÑно, ÑгенеÑиÑÑеÑ, вÑÑиÑлÑеÑÑÑ ÐºÐ°Ðº моÑноÑÑÑ Ð´ÐµÐºÐ°ÑÑова пÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð´Ð²ÑÑ Ð²Ñ Ð¾Ð´Ð½ÑÑ Ð·Ð½Ð°Ñений, ÑÐ¼Ð½Ð¾Ð¶ÐµÐ½Ð½Ð°Ñ Ð½Ð° избиÑаÑелÑноÑÑÑ:
rows = (outer_cardinality * inner_cardinality) * selectivity
= (50 * 10000) * 0.0001
= 50ÐÑли Ð±Ñ Ð¸Ð¼ÐµÐ»Ð¸ÑÑ ÑпиÑки MCV Ð´Ð»Ñ Ð´Ð²ÑÑ
ÑÑолбÑов, ÑÑнкÑией eqjoinsel иÑполÑзовалоÑÑ Ð±Ñ Ð¿ÑÑмое ÑÑавнение Ñо ÑпиÑками MCV Ð´Ð»Ñ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¾Ð±Ñей избиÑаÑелÑноÑÑи Ñой ÑаÑÑи даннÑÑ
, коÑоÑÐ°Ñ ÑодеÑÐ¶Ð¸Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ ÑпиÑка MCV. ÐÑенка оÑÑалÑной ÑаÑÑи даннÑÑ
пÑи ÑÑом вÑполнÑлаÑÑ Ð±Ñ Ð¿ÑедÑÑавленнÑм вÑÑе ÑпоÑобом.
ÐамеÑÑÑе, ÑÑо здеÑÑ Ð²ÑводиÑÑÑ Ð´Ð»Ñ inner_cardinality знаÑение 10000, Ñо еÑÑÑ Ð¸ÑÑ
однÑй ÑÐ°Ð·Ð¼ÐµÑ tenk2. ÐÑли изÑÑиÑÑ Ð²Ñвод EXPLAIN, Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÐºÐ°Ð·Ð°ÑÑÑÑ, ÑÑо оÑенка колиÑеÑÑва ÑÑÑок вÑÑиÑлÑеÑÑÑ ÐºÐ°Ðº 50 * 1, Ñо еÑÑÑ ÑиÑло внеÑниÑ
ÑÑÑок ÑмножаеÑÑÑ Ð½Ð° оÑиенÑиÑовоÑное ÑиÑло ÑÑÑок, полÑÑаемÑÑ
пÑи каждом внÑÑÑеннем ÑканиÑовании индекÑа в tenk2. Ðо ÑÑо не Ñак, Ð²ÐµÐ´Ñ ÑÐ°Ð·Ð¼ÐµÑ ÑезÑлÑÑаÑа ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¾ÑениваеÑÑÑ Ð´Ð¾ Ñого, как вÑбиÑаеÑÑÑ ÐºÐ¾Ð½ÐºÑеÑнÑй план ÑоединениÑ. ÐÑли вÑÑ ÑабоÑÐ°ÐµÑ ÐºÐ¾ÑÑекÑно, оба ваÑианÑа вÑÑиÑÐ»ÐµÐ½Ð¸Ñ ÑÑого ÑазмеÑа Ð´Ð¾Ð»Ð¶Ð½Ñ Ð´Ð°Ð²Ð°ÑÑ Ð¾Ð´Ð¸Ð½ и ÑÐ¾Ñ Ð¶Ðµ оÑвеÑ, но из-за оÑибок окÑÑÐ³Ð»ÐµÐ½Ð¸Ñ Ð¸ дÑÑгиÑ
ÑакÑоÑов иногда они знаÑиÑелÑно ÑазлиÑаÑÑÑÑ.