14.1. ÐÑполÑзование EXPLAIN #
ÐÑполнÑÑ Ð»Ñбой полÑÑеннÑй запÑоÑ, Postgres Pro ÑазÑабаÑÑÐ²Ð°ÐµÑ Ð´Ð»Ñ Ð½ÐµÐ³Ð¾ план запÑоÑа. ÐÑÐ±Ð¾Ñ Ð¿ÑавилÑного плана, ÑооÑвеÑÑÑвÑÑÑего ÑÑÑÑкÑÑÑе запÑоÑа и Ñ
аÑакÑеÑиÑÑикам даннÑм, кÑайне важен Ð´Ð»Ñ Ñ
оÑоÑей пÑоизводиÑелÑноÑÑи, поÑÑÐ¾Ð¼Ñ Ð² ÑиÑÑеме ÑабоÑÐ°ÐµÑ ÑложнÑй планиÑовÑик, задаÑа коÑоÑого â подобÑаÑÑ Ñ
оÑоÑий план. УзнаÑÑ, какой план бÑл вÑбÑан Ð´Ð»Ñ ÐºÐ°ÐºÐ¾Ð³Ð¾-либо запÑоÑа, можно Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ EXPLAIN. Ðонимание плана â ÑÑо иÑкÑÑÑÑво, и ÑÑÐ¾Ð±Ñ Ð¾Ð²Ð»Ð°Ð´ÐµÑÑ Ð¸Ð¼, нÑжен опÑеделÑннÑй опÑÑ, но ÑÑÐ¾Ñ Ñаздел ÑаÑÑÐºÐ°Ð¶ÐµÑ Ð¾ ÑамÑÑ
пÑоÑÑÑÑ
веÑаÑ
.
ÐÑиведÑннÑе ниже пÑимеÑÑ Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ñ Ð½Ð° ÑеÑÑовой базе даннÑÑ
, коÑоÑÐ°Ñ ÑоздаÑÑÑÑ Ð´Ð»Ñ Ð²ÑÑÐ²Ð»ÐµÐ½Ð¸Ñ ÑегÑеÑÑий в иÑÑ
однÑÑ
кодаÑ
PostgreSQL ÑекÑÑей веÑÑии. ÐÐ»Ñ Ð½ÐµÑ Ð¿ÑедваÑиÑелÑно вÑполнÑеÑÑÑ VACUUM ANALYZE. ÐÑ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ð¿Ð¾Ñ
ожие ÑезÑлÑÑаÑÑ, еÑли возÑмÑÑе ÑÑ Ð¶Ðµ Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ
и пÑоделаеÑе ÑледÑÑÑие дейÑÑвиÑ, но пÑимеÑÐ½Ð°Ñ ÑÑоимоÑÑÑ Ð¸ ожидаемое ÑиÑло ÑÑÑок Ñ Ð²Ð°Ñ Ð¼Ð¾Ð¶ÐµÑ Ð½ÐµÐ¼Ð½Ð¾Ð³Ð¾ оÑлиÑаÑÑÑÑ Ð¸Ð·-за Ñого, ÑÑо ÑÑаÑиÑÑика ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ ANALYZE ÑаÑÑÑиÑÑваеÑÑÑ Ð¿Ð¾ ÑлÑÑайной вÑбоÑке, а оÑенки ÑÑоимоÑÑи завиÑÑÑ Ð¾Ñ ÐºÐ¾Ð½ÐºÑеÑной плаÑÑоÑмÑ.
Ð ÑÑиÑ
пÑимеÑаÑ
иÑполÑзÑеÑÑÑ ÑекÑÑовÑй ÑоÑÐ¼Ð°Ñ Ð²Ñвода EXPLAIN, пÑинÑÑÑй по ÑмолÑаниÑ, как более компакÑнÑй и ÑдобнÑй Ð´Ð»Ñ Ð²Ð¾ÑпÑиÑÑÐ¸Ñ Ñеловеком. ÐÑли вÑвод EXPLAIN нÑжно пеÑедаÑÑ ÐºÐ°ÐºÐ¾Ð¹-либо пÑогÑамме Ð´Ð»Ñ Ð´Ð°Ð»ÑнейÑего анализа, лÑÑÑе иÑполÑзоваÑÑ Ð¾Ð´Ð¸Ð½ из маÑинно-оÑиенÑиÑованнÑÑ
ÑоÑмаÑов (XML, JSON или YAML).
14.1.1. ÐÐ·Ñ EXPLAIN #
СÑÑÑкÑÑÑа плана запÑоÑа пÑедÑÑавлÑÐµÑ Ñобой деÑево Ñзлов плана. Ð£Ð·Ð»Ñ Ð½Ð° нижнем ÑÑовне деÑева â ÑÑо ÑÐ·Ð»Ñ ÑканиÑованиÑ, коÑоÑÑе возвÑаÑаÑÑ Ð½ÐµÐ¾Ð±ÑабоÑаннÑе даннÑе ÑаблиÑÑ. РазнÑм Ñипам доÑÑÑпа к ÑаблиÑе ÑооÑвеÑÑÑвÑÑÑ ÑазнÑе ÑзлÑ: поÑледоваÑелÑное ÑканиÑование, ÑканиÑование индекÑа и ÑканиÑование биÑовой каÑÑÑ. ÐÑÑоÑниками ÑÑÑок могÑÑ Ð±ÑÑÑ Ð½Ðµ ÑолÑко ÑаблиÑÑ, но и напÑимеÑ, пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ VALUES и ÑÑнкÑии, возвÑаÑаÑÑие множеÑÑва во FROM, и они пÑедÑÑавлÑÑÑÑÑ Ð¾ÑделÑнÑми Ñипами Ñзлов ÑканиÑованиÑ. ÐÑли запÑÐ¾Ñ ÑÑебÑÐµÑ Ð¾Ð±ÑединениÑ, агÑегаÑнÑÑ
вÑÑиÑлений, ÑоÑÑиÑовки или дÑÑгиÑ
опеÑаÑий Ñ Ð¸ÑÑ
однÑми ÑÑÑоками, над Ñзлами ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ÑвлÑÑÑÑÑ ÑзлÑ, обознаÑаÑÑие ÑÑи опеÑаÑии. Ð Ñак как обÑÑно опеÑаÑии могÑÑ Ð²ÑполнÑÑÑÑÑ ÑазнÑми ÑпоÑобами, на ÑÑом ÑÑовне Ñоже могÑÑ Ð±ÑÑÑ ÑÐ·Ð»Ñ ÑазнÑÑ
Ñипов. РвÑводе ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ EXPLAIN Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñзла в деÑеве плана оÑводиÑÑÑ Ð¾Ð´Ð½Ð° ÑÑÑока, где показÑваеÑÑÑ Ð±Ð°Ð·Ð¾Ð²Ñй Ñип Ñзла плÑÑ Ð¾Ñенка ÑÑоимоÑÑи вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ Ñзла, коÑоÑÑÑ Ñделал Ð´Ð»Ñ Ð½ÐµÐ³Ð¾ планиÑовÑик. ÐÑли Ð´Ð»Ñ Ñзла вÑводÑÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе ÑвойÑÑва, в вÑвод могÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÑÑÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе ÑÑÑоки, Ñ Ð¾ÑÑÑÑпом Ð¾Ñ Ð¾Ñновной инÑоÑмаÑии Ñзла. Ð Ñамой пеÑвой ÑÑÑоке (оÑновной ÑÑÑоке Ñамого веÑÑ
него Ñзла) вÑводиÑÑÑ Ð¾Ð±ÑÐ°Ñ ÑÑоимоÑÑÑ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð²Ñего плана; именно ÑÑо знаÑение планиÑовÑик ÑÑаÑаеÑÑÑ Ð¼Ð¸Ð½Ð¸Ð¼Ð¸Ð·Ð¸ÑоваÑÑ.
ÐзглÑниÑе на ÑледÑÑÑий пÑоÑÑейÑий пÑимеÑ, пÑоÑÑо иллÑÑÑÑиÑÑÑÑий ÑоÑÐ¼Ð°Ñ Ð²Ñвода:
EXPLAIN SELECT * FROM tenk1;
QUERY PLAN
-------------------------------------------------------------
Seq Scan on tenk1 (cost=0.00..458.00 rows=10000 width=244)
ÐÑÐ¾Ñ Ð·Ð°Ð¿ÑÐ¾Ñ Ð½Ðµ ÑодеÑÐ¶Ð¸Ñ Ð¿ÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ WHERE, поÑÑÐ¾Ð¼Ñ Ð¾Ð½ должен пÑоÑканиÑоваÑÑ Ð²Ñе ÑÑÑоки ÑаблиÑÑ, Ñак ÑÑо планиÑовÑик вÑбÑал план пÑоÑÑого поÑледоваÑелÑного ÑканиÑованиÑ. ЧиÑла, пеÑеÑиÑленнÑе в ÑкобкаÑ
(Ñлева напÑаво), имеÑÑ ÑледÑÑÑий ÑмÑÑл:
ÐÑиблизиÑелÑÐ½Ð°Ñ ÑÑоимоÑÑÑ Ð·Ð°Ð¿ÑÑка. ÐÑо вÑемÑ, коÑоÑое пÑÐ¾Ñ Ð¾Ð´Ð¸Ñ, пÑежде Ñем наÑнÑÑÑÑ ÑÑап вÑвода даннÑÑ , напÑÐ¸Ð¼ÐµÑ Ð´Ð»Ñ ÑоÑÑиÑÑÑÑего Ñзла ÑÑо вÑÐµÐ¼Ñ ÑоÑÑиÑовки.
ÐÑиблизиÑелÑÐ½Ð°Ñ Ð¾Ð±ÑÐ°Ñ ÑÑоимоÑÑÑ. Ðна вÑÑиÑлÑеÑÑÑ Ð² пÑедположении, ÑÑо Ñзел плана вÑполнÑеÑÑÑ Ð´Ð¾ конÑа, Ñо еÑÑÑ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ Ð²Ñе доÑÑÑпнÑе ÑÑÑоки. Ðа пÑакÑике ÑодиÑелÑÑкий Ñзел Ð¼Ð¾Ð¶ÐµÑ Ð´Ð¾ÑÑоÑно пÑекÑаÑиÑÑ ÑÑение ÑÑÑок доÑеÑнего (Ñм. пÑиведÑннÑй ниже пÑÐ¸Ð¼ÐµÑ Ñ
LIMIT).Ðжидаемое ÑиÑло ÑÑÑок, коÑоÑое должен вÑвеÑÑи ÑÑÐ¾Ñ Ñзел плана. ÐÑи ÑÑом Ñак же пÑедполагаеÑÑÑ, ÑÑо Ñзел вÑполнÑеÑÑÑ Ð´Ð¾ конÑа.
ÐжидаемÑй ÑÑедний ÑÐ°Ð·Ð¼ÐµÑ ÑÑÑок, вÑводимÑÑ ÑÑим Ñзлом плана (в байÑÐ°Ñ ).
СÑоимоÑÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð·Ð¼ÐµÑÑÑÑÑÑ Ð² пÑоизволÑнÑÑ
единиÑаÑ
, опÑеделÑемÑÑ
паÑамеÑÑами планиÑовÑика (Ñм. ÐодÑаздел 18.7.2). ТÑадиÑионно единиÑей ÑÑоимоÑÑи ÑÑиÑаеÑÑÑ Ð¾Ð¿ÐµÑаÑÐ¸Ñ ÑÑÐµÐ½Ð¸Ñ ÑÑÑаниÑÑ Ñ Ð´Ð¸Ñка; Ñо еÑÑÑ seq_page_cost обÑÑно Ñавен 1.0, а дÑÑгие паÑамеÑÑÑ Ð·Ð°Ð´Ð°ÑÑÑÑ Ð¾ÑноÑиÑелÑно него. ÐÑимеÑÑ Ð² ÑÑом Ñазделе вÑполнÑÑÑÑÑ Ñо ÑÑандаÑÑнÑми паÑамеÑÑами ÑÑоимоÑÑи.
Ðажно понимаÑÑ, ÑÑо ÑÑоимоÑÑÑ Ñзла веÑÑ Ð½ÐµÐ³Ð¾ ÑÑÐ¾Ð²Ð½Ñ Ð²ÐºÐ»ÑÑÐ°ÐµÑ ÑÑоимоÑÑÑ Ð²ÑÐµÑ ÐµÐ³Ð¾ поÑомков. Также важно оÑознаваÑÑ, ÑÑо ÑÑа ÑÑоимоÑÑÑ Ð¾ÑÑÐ°Ð¶Ð°ÐµÑ ÑолÑко Ñе ÑакÑоÑÑ, коÑоÑÑе ÑÑиÑÑÐ²Ð°ÐµÑ Ð¿Ð»Ð°Ð½Ð¸ÑовÑик. Ð ÑаÑÑноÑÑи, она не завиÑÐ¸Ñ Ð¾Ñ Ð²Ñемени, Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾Ð³Ð¾ Ð´Ð»Ñ Ð¿ÐµÑедаÑи ÑезÑлÑÑиÑÑÑÑÐ¸Ñ ÑÑÑок клиенÑÑ, Ñ Ð¾ÑÑ Ð¾Ð½Ð¾ Ð¼Ð¾Ð¶ÐµÑ ÑоÑÑавлÑÑÑ Ð·Ð½Ð°ÑиÑелÑнÑÑ ÑаÑÑÑ Ð¾Ð±Ñего вÑемени вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа. Тем не менее планиÑовÑик игноÑиÑÑÐµÑ ÑÑÑ Ð²ÐµÐ»Ð¸ÑинÑ, Ñак как он вÑÑ Ñавно не ÑÐ¼Ð¾Ð¶ÐµÑ Ð¸Ð·Ð¼ÐµÐ½Ð¸ÑÑ ÐµÑ, вÑбÑав дÑÑгой план. (ÐÑ Ð²ÐµÑим в Ñо, ÑÑо лÑбой пÑавилÑнÑй план запÑоÑа вÑдаÑÑ Ð¾Ð´Ð¸Ð½ и ÑÐ¾Ñ Ð¶Ðµ Ð½Ð°Ð±Ð¾Ñ ÑÑÑок.)
ÐнаÑение rows здеÑÑ Ð¸Ð¼ÐµÐµÑ Ð¾ÑобенноÑÑÑ â оно вÑÑÐ°Ð¶Ð°ÐµÑ Ð½Ðµ ÑиÑло ÑÑÑок, обÑабоÑаннÑÑ
или пÑоÑканиÑованнÑÑ
Ñзлом плана, а ÑиÑло ÑÑÑок, вÑданнÑÑ
ÑÑим Ñзлом. ЧаÑÑо оно окажеÑÑÑ Ð¼ÐµÐ½ÑÑе ÑиÑла пÑоÑканиÑованнÑÑ
ÑÑÑок в ÑезÑлÑÑаÑе пÑименÑнной к ÑÐ·Ð»Ñ ÑилÑÑÑаÑии по ÑÑловиÑм WHERE. Ридеале, на веÑÑ
нем ÑÑовне ÑÑо знаÑение бÑÐ´ÐµÑ Ð¿ÑиблизиÑелÑно Ñавно ÑиÑÐ»Ñ ÑÑÑок, коÑоÑое ÑакÑиÑеÑки возвÑаÑаеÑ, изменÑÐµÑ Ð¸Ð»Ð¸ ÑдалÑÐµÑ Ð·Ð°Ð¿ÑоÑ.
ÐозвÑаÑаÑÑÑ Ðº наÑÐµÐ¼Ñ Ð¿ÑимеÑÑ:
EXPLAIN SELECT * FROM tenk1;
QUERY PLAN
-------------------------------------------------------------
Seq Scan on tenk1 (cost=0.00..458.00 rows=10000 width=244)
ÐÑи ÑиÑла полÑÑаÑÑÑÑ Ð¾ÑÐµÐ½Ñ Ð¿ÑоÑÑо. ÐÑполниÑе:
SELECT relpages, reltuples FROM pg_class WHERE relname = 'tenk1';
и Ð²Ñ ÑвидиÑе, ÑÑо tenk1 ÑодеÑÐ¶Ð¸Ñ 358 ÑÑÑÐ°Ð½Ð¸Ñ Ð´Ð¸Ñка и 10000 ÑÑÑок. ÐбÑÐ°Ñ ÑÑоимоÑÑÑ Ð²ÑÑиÑлÑеÑÑÑ ÐºÐ°Ðº (ÑиÑло_ÑÑений_диÑка * seq_page_cost) + (ÑиÑло_пÑоÑканиÑованнÑÑ
_ÑÑÑок * cpu_tuple_cost). Ðо ÑмолÑаниÑ, seq_page_cost Ñавно 1.0, а cpu_tuple_cost â 0.01, Ñак ÑÑо пÑиблизиÑелÑÐ½Ð°Ñ ÑÑоимоÑÑÑ Ð·Ð°Ð¿ÑоÑа Ñавна (358 * 1.0) + (10000 * 0.01) = 458.
ТепеÑÑ Ð´Ð°Ð²Ð°Ð¹Ñе изменим запÑоÑ, добавив в него пÑедложение WHERE:
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 7000;
QUERY PLAN
------------------------------------------------------------
Seq Scan on tenk1 (cost=0.00..483.00 rows=7001 width=244)
Filter: (unique1 < 7000)
ÐамеÑÑÑе, ÑÑо в вÑводе EXPLAIN показано, ÑÑо ÑÑловие WHERE пÑименено как «ÑилÑÑÑ» к ÑÐ·Ð»Ñ Ð¿Ð»Ð°Ð½Ð° Seq Scan (ÐоÑледоваÑелÑное ÑканиÑование). ÐÑо ознаÑаеÑ, ÑÑо Ñзел плана пÑовеÑÑÐµÑ ÑÑо ÑÑловие Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ пÑоÑканиÑованного им Ñзла и вÑÐ²Ð¾Ð´Ð¸Ñ ÑолÑко Ñе ÑÑÑоки, коÑоÑÑе ÑдовлеÑвоÑÑÑÑ ÐµÐ¼Ñ. ÐÑедложение WHERE повлиÑло на оÑÐµÐ½ÐºÑ ÑиÑла вÑÑ
однÑÑ
ÑÑÑок. Ðднако пÑи ÑканиÑовании поÑÑебÑеÑÑÑ Ð¿ÑоÑиÑаÑÑ Ð²Ñе 10000 ÑÑÑок, поÑÑÐ¾Ð¼Ñ Ð¾Ð±ÑÐ°Ñ ÑÑоимоÑÑÑ Ð½Ðµ ÑменÑÑилаÑÑ. Ðа деле она даже немного ÑвелиÑилаÑÑ (на 10000 * cpu_operator_cost, еÑли бÑÑÑ ÑоÑнÑми), оÑÑÐ°Ð¶Ð°Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑное вÑемÑ, коÑоÑое поÑÑебÑеÑÑÑ Ð¿ÑоÑеÑÑоÑÑ Ð½Ð° пÑовеÑÐºÑ ÑÑÐ»Ð¾Ð²Ð¸Ñ WHERE.
ФакÑиÑеÑкое ÑиÑло ÑÑÑок ÑезÑлÑÑаÑа ÑÑого запÑоÑа бÑÐ´ÐµÑ Ñавно 7000, но знаÑение rows даÑÑ ÑолÑко пÑиблизиÑелÑное знаÑение. ÐÑли Ð²Ñ Ð¿Ð¾Ð¿ÑÑаеÑеÑÑ Ð¿Ð¾Ð²ÑоÑиÑÑ ÑÑÐ¾Ñ ÑкÑпеÑименÑ, Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе полÑÑиÑÑ Ð½ÐµÐ¼Ð½Ð¾Ð³Ð¾ дÑÑгÑÑ Ð¾ÑенкÑ; более Ñого, она Ð¼Ð¾Ð¶ÐµÑ Ð¼ÐµÐ½ÑÑÑÑÑ Ð¿Ð¾Ñле каждой ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ ANALYZE, Ñак как ANALYZE полÑÑÐ°ÐµÑ ÑÑаÑиÑÑÐ¸ÐºÑ Ð¿Ð¾ ÑлÑÑайной вÑбоÑке ÑаблиÑÑ.
ТепеÑÑ Ð´Ð°Ð²Ð°Ð¹Ñе Ñделаем огÑаниÑение более избиÑаÑелÑнÑм:
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100;
QUERY PLAN
-------------------------------------------------------------------â-----------
Bitmap Heap Scan on tenk1 (cost=5.07..229.20 rows=101 width=244)
Recheck Cond: (unique1 < 100)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0)
Рданном ÑлÑÑае планиÑовÑик ÑеÑил иÑполÑзоваÑÑ Ð¿Ð»Ð°Ð½ из двÑÑ ÑÑапов: ÑнаÑала доÑеÑний Ñзел плана пÑоÑмаÑÑÐ¸Ð²Ð°ÐµÑ Ð¸Ð½Ð´ÐµÐºÑ Ð¸ Ð½Ð°Ñ Ð¾Ð´Ð¸Ñ Ð² нÑм адÑеÑа ÑÑÑок, ÑооÑвеÑÑÑвÑÑÑÐ¸Ñ ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑа, а заÑем веÑÑ Ð½Ð¸Ð¹ Ñзел ÑобÑÑвенно вÑбиÑÐ°ÐµÑ ÑÑи ÑÑÑоки из ÑаблиÑÑ. ÐÑбиÑаÑÑ ÑÑÑоки по оÑделÑноÑÑи гоÑаздо доÑоже, Ñем пÑоÑÑо ÑиÑаÑÑ Ð¸Ñ Ð¿Ð¾ÑледоваÑелÑно, но Ñак как ÑиÑаÑÑ Ð¿ÑидÑÑÑÑ Ð½Ðµ вÑе ÑÑÑаниÑÑ ÑаблиÑÑ, ÑÑо вÑÑ Ñавно бÑÐ´ÐµÑ Ð´ÐµÑевле, Ñем ÑканиÑоваÑÑ Ð²ÑÑ ÑаблиÑÑ. (ÐÑполÑзование двÑÑ ÑÑовней плана обÑÑÑнÑеÑÑÑ Ñем, ÑÑо веÑÑ Ð½Ð¸Ð¹ Ñзел ÑоÑÑиÑÑÐµÑ Ð°Ð´ÑеÑа ÑÑÑок, вÑбÑаннÑÑ Ð¸Ð· индекÑа, в ÑизиÑеÑком поÑÑдке, пÑежде Ñем ÑиÑаÑÑ, ÑÑÐ¾Ð±Ñ ÑнизиÑÑ ÑÑоимоÑÑÑ Ð¾ÑделÑнÑÑ ÑÑений. Слово «bitmap» (биÑÐ¾Ð²Ð°Ñ ÐºÐ°ÑÑа) в имени Ñзла обознаÑÐ°ÐµÑ Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼, вÑполнÑÑÑий ÑоÑÑиÑовкÑ.)
ТепеÑÑ Ð´Ð°Ð²Ð°Ð¹Ñе добавим еÑÑ Ð¾Ð´Ð½Ð¾ ÑÑловие в пÑедложение WHERE:
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND stringu1 = 'xxx';
QUERY PLAN
-------------------------------------------------------------------â-----------
Bitmap Heap Scan on tenk1 (cost=5.04..229.43 rows=1 width=244)
Recheck Cond: (unique1 < 100)
Filter: (stringu1 = 'xxx'::name)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0)
Index Cond: (unique1 < 100)
Ðобавленное ÑÑловие stringu1 = 'xxx' ÑменÑÑÐ°ÐµÑ Ð¾ÑÐµÐ½ÐºÑ ÑиÑла ÑезÑлÑÑиÑÑÑÑиÑ
ÑÑÑок, но не ÑÑоимоÑÑÑ Ð·Ð°Ð¿ÑоÑа, Ñак как пÑоÑмаÑÑиваÑÑÑÑ Ð±ÑÐ´ÐµÑ ÑÐ¾Ñ Ð¶Ðµ Ð½Ð°Ð±Ð¾Ñ ÑÑÑок, ÑÑо и ÑанÑÑе. ÐамеÑÑÑе, ÑÑо ÑÑловие на stringu1 не добавлÑеÑÑÑ Ð² каÑеÑÑве ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑа, Ñак как Ð¸Ð½Ð´ÐµÐºÑ Ð¿Ð¾ÑÑÑоен ÑолÑко по ÑÑолбÑÑ unique1. ÐмеÑÑо ÑÑого оно пÑименÑеÑÑÑ ÐºÐ°Ðº ÑилÑÑÑ Ðº ÑÑÑокам, полÑÑеннÑм по индекÑÑ. Ð ÑезÑлÑÑаÑе ÑÑоимоÑÑÑ Ð´Ð°Ð¶Ðµ немного ÑвелиÑилаÑÑ, оÑÑÐ°Ð¶Ð°Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ðµ ÑÑой пÑовеÑки.
РнекоÑоÑÑÑ ÑлÑÑаÑÑ Ð¿Ð»Ð°Ð½Ð¸ÑовÑик пÑедпоÑÑÑÑ Â«Ð¿ÑоÑÑой» план ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑа:
EXPLAIN SELECT * FROM tenk1 WHERE unique1 = 42;
QUERY PLAN
-------------------------------------------------------------------â----------
Index Scan using tenk1_unique1 on tenk1 (cost=0.29..8.30 rows=1 width=244)
Index Cond: (unique1 = 42)
Рплане Ñакого Ñипа ÑÑÑоки ÑаблиÑÑ Ð²ÑбиÑаÑÑÑÑ Ð² поÑÑдке индекÑа, в ÑезÑлÑÑаÑе Ñего ÑÑение иÑ
обÑ
одиÑÑÑ Ð´Ð¾Ñоже, но Ñак как иÑ
немного, дополниÑелÑно ÑоÑÑиÑоваÑÑ Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑÑÑок не ÑÑоиÑ. ÐÑ ÑаÑÑо бÑдеÑе вÑÑÑеÑаÑÑ ÑÑÐ¾Ñ Ñип плана в запÑоÑаÑ
, коÑоÑÑе вÑбиÑаÑÑ Ð²Ñего Ð¾Ð´Ð½Ñ ÑÑÑокÑ. Также он ÑаÑÑо задейÑÑвÑеÑÑÑ Ñам, где ÑÑловие ORDER BY ÑооÑвеÑÑÑвÑÐµÑ Ð¿Ð¾ÑÑÐ´ÐºÑ Ð¸Ð½Ð´ÐµÐºÑа, Ñак как в ÑÑиÑ
ÑлÑÑаÑÑ
Ð´Ð»Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ORDER BY не ÑÑебÑеÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑй Ñаг ÑоÑÑиÑовки. Ð ÑÑом пÑимеÑе Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð½Ð°Ñ ÐºÐ¾Ð½ÑÑÑÑкÑÐ¸Ñ ORDER BY unique1 бÑÐ´ÐµÑ Ð¸ÑполÑзоваÑÑ ÑÐ¾Ñ Ð¶Ðµ план, поÑÐ¾Ð¼Ñ ÑÑо Ð¸Ð½Ð´ÐµÐºÑ Ñже неÑвно обеÑпеÑÐ¸Ð²Ð°ÐµÑ Ð½ÑжнÑй поÑÑдок.
ÐланиÑовÑик Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð±ÑабоÑаÑÑ ÐºÐ¾Ð½ÑÑÑÑкÑÐ¸Ñ ORDER BY неÑколÑкими ÑпоÑобами. ÐÑедÑдÑÑий пÑÐ¸Ð¼ÐµÑ Ð¿Ð¾ÐºÐ°Ð·ÑваеÑ, ÑÑо нÑжнÑй поÑÑдок Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿Ð¾Ð»ÑÑен неÑвнÑм обÑазом. Также планиÑовÑик Ð¼Ð¾Ð¶ÐµÑ Ð·Ð°Ð´ÐµÐ¹ÑÑвоваÑÑ ÑвнÑÑ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Sort:
EXPLAIN SELECT * FROM tenk1 ORDER BY unique1;
QUERY PLAN
-------------------------------------------------------------------
Sort (cost=1109.39..1134.39 rows=10000 width=244)
Sort Key: unique1
-> Seq Scan on tenk1 (cost=0.00..445.00 rows=10000 width=244)
ÐÑли подплан гаÑанÑиÑÑÐµÑ ÑоÑÑиÑÐ¾Ð²ÐºÑ Ð¿Ð¾ пÑеÑикÑÑ Ð·Ð°Ð´Ð°Ð½Ð½ÑÑ
клÑÑей ÑоÑÑиÑовки, планиÑовÑик Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑимениÑÑ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Incremental sort (инкÑеменÑалÑнÑÑ ÑоÑÑиÑовкÑ):
EXPLAIN SELECT * FROM tenk1 ORDER BY four, ten LIMIT 100;
QUERY PLAN
-------------------------------------------------------------------â-----------------------------------
Limit (cost=521.06..538.05 rows=100 width=244)
-> Incremental Sort (cost=521.06..2220.95 rows=10000 width=244)
Sort Key: four, ten
Presorted Key: four
-> Index Scan using index_tenk1_on_four on tenk1 (cost=0.29..1510.08 rows=10000 width=244)
С инкÑеменÑалÑной ÑоÑÑиÑовкой, в оÑлиÑие Ð¾Ñ Ð¾Ð±ÑÑной, коÑÑежи могÑÑ Ð²ÑдаваÑÑÑÑ Ð´Ð¾ завеÑÑÐµÐ½Ð¸Ñ ÑоÑÑиÑовки вÑего ÑезÑлÑÑаÑа, ÑÑо в ÑаÑÑноÑÑи позволÑÐµÑ Ð¾Ð¿ÑимизиÑоваÑÑ Ð·Ð°Ð¿ÑоÑÑ Ñ LIMIT. ÐÑоме Ñого, Ð´Ð»Ñ Ð¸Ð½ÐºÑеменÑалÑной ÑоÑÑиÑовки Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑÑебоваÑÑÑÑ Ð¼ÐµÐ½ÑÑе памÑÑи, вÑледÑÑвие Ñего ÑменÑÑаеÑÑÑ Ð²ÐµÑоÑÑноÑÑÑ Ð²ÑÑеÑÐ½ÐµÐ½Ð¸Ñ ÑоÑÑиÑÑемÑÑ
даннÑÑ
на диÑк, но Ñ Ð´ÑÑгой ÑÑоÑонÑ, ÑÑебÑеÑÑÑ ÑазделÑÑÑ ÑезÑлÑÑиÑÑÑÑее множеÑÑво на неÑколÑко ÑаÑÑей, ÑÑо влеÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе накладнÑе ÑаÑÑ
одÑ.
ÐÑли в ÑаблиÑе еÑÑÑ Ð¾ÑделÑнÑе индекÑÑ Ð¿Ð¾ ÑазнÑм ÑÑолбÑам, ÑигÑÑиÑÑÑÑим в WHERE, планиÑовÑик Ð¼Ð¾Ð¶ÐµÑ Ð²ÑбÑаÑÑ ÑоÑеÑание ÑÑиÑ
индекÑов (Ñ AND и OR):
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000;
QUERY PLAN
-------------------------------------------------------------------â------------------
Bitmap Heap Scan on tenk1 (cost=25.08..60.21 rows=10 width=244)
Recheck Cond: ((unique1 < 100) AND (unique2 > 9000))
-> BitmapAnd (cost=25.08..25.08 rows=10 width=0)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0)
Index Cond: (unique1 < 100)
-> Bitmap Index Scan on tenk1_unique2 (cost=0.00..19.78 rows=999 width=0)
Index Cond: (unique2 > 9000)
Ðо Ð´Ð»Ñ ÑÑого поÑÑебÑеÑÑÑ Ð¾Ð±Ð¾Ð¹Ñи оба индекÑа, Ñак ÑÑо ÑÑо не обÑзаÑелÑно бÑÐ´ÐµÑ Ð²Ñгоднее, Ñем пÑоÑÑо пÑоÑмоÑÑеÑÑ Ð¾Ð´Ð¸Ð½ индекÑ, а вÑоÑое ÑÑловие обÑабоÑаÑÑ ÐºÐ°Ðº ÑилÑÑÑ. ÐзмениÑе диапазон и Ð²Ñ ÑвидиÑе, как ÑÑо повлиÑÐµÑ Ð½Ð° план.
СледÑÑÑий пÑÐ¸Ð¼ÐµÑ Ð¸Ð»Ð»ÑÑÑÑиÑÑÐµÑ ÑÑÑекÑÑ LIMIT:
EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2;
QUERY PLAN
-------------------------------------------------------------------â------------------
Limit (cost=0.29..14.48 rows=2 width=244)
-> Index Scan using tenk1_unique2 on tenk1 (cost=0.29..71.27 rows=10 width=244)
Index Cond: (unique2 > 9000)
Filter: (unique1 < 100)
ÐÑо ÑÐ¾Ñ Ð¶Ðµ запÑоÑ, ÑÑо и ÑанÑÑе, но добавили Ð¼Ñ Ð² него LIMIT, ÑÑÐ¾Ð±Ñ Ð²Ð¾Ð·Ð²ÑаÑалиÑÑ Ð½Ðµ вÑе ÑÑÑоки, и планиÑовÑик ÑеÑÐ°ÐµÑ Ð²ÑполнÑÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð¿Ð¾-дÑÑгомÑ. ÐамеÑÑÑе, ÑÑо обÑÐ°Ñ ÑÑоимоÑÑÑ Ð¸ ÑиÑло ÑÑÑок Ð´Ð»Ñ Ñзла Index Scan ÑаÑÑÑиÑÑваÑÑÑÑ Ð² пÑедположении, ÑÑо он бÑÐ´ÐµÑ Ð²ÑполнÑÑÑÑÑ Ð¿Ð¾Ð»Ð½Ð¾ÑÑÑÑ. Ðднако Ñзел Limit должен оÑÑановиÑÑÑÑ, полÑÑив ÑолÑко пÑÑÑÑ ÑаÑÑÑ Ð²ÑеÑ
ÑÑÑок, Ñак ÑÑо его ÑÑоимоÑÑÑ Ð±ÑÐ´ÐµÑ ÑоÑÑавлÑÑÑ Ð¾Ð´Ð½Ñ Ð¿ÑÑÑÑ Ð¾Ñ Ð²ÑÑиÑленной Ñанее, и ÑÑо и бÑÐ´ÐµÑ Ð¸Ñоговой оÑенкой ÑÑоимоÑÑи запÑоÑа. С дÑÑгой ÑÑоÑонÑ, планиÑовÑик мог Ð±Ñ Ð¿ÑоÑÑо добавиÑÑ Ð² пÑедÑдÑÑий план Ñзел Limit, но ÑÑо не избавило Ð±Ñ Ð¾Ñ Ð·Ð°ÑÑÐ°Ñ Ð½Ð° запÑÑк ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð±Ð¸Ñовой каÑÑÑ, а знаÑиÑ, обÑÐ°Ñ ÑÑоимоÑÑÑ Ð±Ñла Ð±Ñ Ð²ÑÑе 25 единиÑ.
ÐавайÑе попÑобÑем ÑоединиÑÑ Ð´Ð²Ðµ ÑаблиÑÑ Ð¿Ð¾ ÑÑолбÑам, коÑоÑÑе Ð¼Ñ Ñже иÑполÑзовали:
EXPLAIN SELECT *
FROM tenk1 t1, tenk2 t2
WHERE t1.unique1 < 10 AND t1.unique2 = t2.unique2;
QUERY PLAN
-------------------------------------------------------------------â-------------------
Nested Loop (cost=4.65..118.62 rows=10 width=488)
-> Bitmap Heap Scan on tenk1 t1 (cost=4.36..39.47 rows=10 width=244)
Recheck Cond: (unique1 < 10)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.36 rows=10 width=0)
Index Cond: (unique1 < 10)
-> Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.29..7.91 rows=1 width=244)
Index Cond: (unique2 = t1.unique2)
Ð ÑÑом плане поÑвлÑеÑÑÑ Ñзел ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½Ñм Ñиклом, на вÑ
од коÑоÑÐ¾Ð¼Ñ Ð¿Ð¾ÑÑÑпаÑÑ Ð´Ð°Ð½Ð½Ñе Ð¾Ñ Ð´Ð²ÑÑ
его поÑомков, Ñзлов ÑканиÑованиÑ. ÐÑÑ ÑÑÑÑкÑÑÑÑ Ð¿Ð»Ð°Ð½Ð° оÑÑÐ°Ð¶Ð°ÐµÑ Ð¾ÑÑÑÑп оÑновнÑÑ
ÑÑÑок его Ñзлов. ÐеÑвÑй, или «внеÑний», поÑомок ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ â Ñзел ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð±Ð¸Ñовой каÑÑÑ, поÑ
ожий на Ñе, ÑÑо Ð¼Ñ Ð²Ð¸Ð´ÐµÐ»Ð¸ ÑанÑÑе. Ðго ÑÑоимоÑÑÑ Ð¸ ÑиÑло ÑÑÑок Ñе же, ÑÑо Ð¼Ñ Ð¿Ð¾Ð»ÑÑили Ð±Ñ Ð´Ð»Ñ Ð·Ð°Ð¿ÑоÑа SELECT ... WHERE unique1 < 10, Ñак как к ÑÑÐ¾Ð¼Ñ ÑÐ·Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¾ пÑедложение WHERE unique1 < 10. УÑловие t1.unique2 = t2.unique2 еÑÑ Ð½Ðµ ÑÑиÑÑваеÑÑÑ, поÑÑÐ¾Ð¼Ñ Ð¾Ð½Ð¾ не влиÑÐµÑ Ð½Ð° ÑиÑло ÑÑÑок Ñзла внеÑнего ÑканиÑованиÑ. Узел ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½Ñм Ñиклом бÑÐ´ÐµÑ Ð²ÑполнÑÑÑ Ñзел «внÑÑÑеннего» поÑомка Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑÑÑоки, полÑÑенной из внеÑнего поÑомка. ÐнаÑÐµÐ½Ð¸Ñ ÑÑолбÑов из ÑекÑÑей внеÑней ÑÑÑоки могÑÑ Ð¸ÑполÑзоваÑÑÑÑ Ð²Ð¾ внÑÑÑеннем ÑканиÑовании (в данном ÑлÑÑае ÑÑо знаÑение t1.unique2), поÑÑÐ¾Ð¼Ñ Ð¼Ñ Ð¿Ð¾Ð»ÑÑаем план и ÑÑоимоÑÑÑ Ð¿ÑимеÑно Ñакие, как и ÑанÑÑе Ð´Ð»Ñ Ð¿ÑоÑÑого запÑоÑа SELECT ... WHERE t2.unique2 = . (Ðа Ñамом деле оÑеноÑÐ½Ð°Ñ ÑÑоимоÑÑÑ Ð½ÐµÐ¼Ð½Ð¾Ð³Ð¾ менÑÑе, в пÑедположении, ÑÑо пÑи неоднокÑаÑном ÑканиÑовании индекÑа по конÑÑанÑаt2 положиÑелÑнÑÑ ÑÐ¾Ð»Ñ ÑÑгÑÐ°ÐµÑ ÐºÐµÑиÑование.) Ð ÑезÑлÑÑаÑе ÑÑоимоÑÑÑ Ñзла Ñикла ÑкладÑваеÑÑÑ Ð¸Ð· ÑÑоимоÑÑи внеÑнего ÑканиÑованиÑ, ÑÐµÐ½Ñ Ð²Ð½ÑÑÑеннего ÑканиÑованиÑ, Ñмноженной на ÑиÑло ÑÑÑок (здеÑÑ 10 * 7.91), и неболÑÑой наÑенки за обÑабоÑÐºÑ ÑоединениÑ.
Ð ÑÑом пÑимеÑе ÑиÑло вÑÑ
однÑÑ
ÑÑÑок ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñавно пÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ ÑиÑел ÑÑÑок двÑÑ
Ñзлов ÑканиÑованиÑ, но ÑÑо не вÑегда бÑÐ´ÐµÑ Ñак, поÑÐ¾Ð¼Ñ ÑÑо в дополниÑелÑнÑÑ
ÑÑловиÑÑ
WHERE могÑÑ ÑпоминаÑÑÑÑ Ð¾Ð±Ðµ ÑаблиÑÑ, Ñак ÑÑо пÑимениÑÑ Ð¸Ñ
можно бÑÐ´ÐµÑ ÑолÑко в ÑоÑке ÑоединениÑ, а не в одном из Ñзлов ÑканиÑованиÑ. ÐапÑимеÑ:
EXPLAIN SELECT *
FROM tenk1 t1, tenk2 t2
WHERE t1.unique1 < 10 AND t2.unique2 < 10 AND t1.hundred < t2.hundred;
QUERY PLAN
-------------------------------------------------------------------â--------------------------
Nested Loop (cost=4.65..49.46 rows=33 width=488)
Join Filter: (t1.hundred < t2.hundred)
-> Bitmap Heap Scan on tenk1 t1 (cost=4.36..39.47 rows=10 width=244)
Recheck Cond: (unique1 < 10)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.36 rows=10 width=0)
Index Cond: (unique1 < 10)
-> Materialize (cost=0.29..8.51 rows=10 width=244)
-> Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.29..8.46 rows=10 width=244)
Index Cond: (unique2 < 10)
УÑловие t1.hundred < t2.hundred не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÑовеÑено в индекÑе tenk2_unique2, поÑÑÐ¾Ð¼Ñ Ð¾Ð½Ð¾ пÑименÑеÑÑÑ Ð² Ñзле ÑоединениÑ. ÐÑо ÑменÑÑÐ°ÐµÑ Ð¾ÑÐµÐ½ÐºÑ ÑиÑла вÑÑ
однÑÑ
ÑÑÑок, Ñогда как ÑиÑло ÑÑÑок в ÑзлаÑ
ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ менÑеÑÑÑ.
ÐамеÑÑÑе, ÑÑо здеÑÑ Ð¿Ð»Ð°Ð½Ð¸ÑовÑик ÑеÑил «маÑеÑиализоваÑÑ» внÑÑÑеннее оÑноÑение ÑоединениÑ, помеÑÑив повеÑÑ
него Ñзел плана Materialize (ÐаÑеÑиализоваÑÑ). ÐÑо знаÑиÑ, ÑÑо ÑканиÑование индекÑа t2 бÑÐ´ÐµÑ Ð²ÑполнÑÑÑÑÑ ÑолÑко единождÑ, пÑи Ñом, ÑÑо ÑÐ·Ð»Ñ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½Ð¾Ð³Ð¾ Ñикла ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾ÑÑебÑеÑÑÑ Ð¿ÑоÑиÑаÑÑ Ð´Ð°Ð½Ð½Ñе деÑÑÑÑ Ñаз, по ÑиÑÐ»Ñ ÑÑÑок во внеÑнем Ñоединении. Узел Materialize ÑоÑ
ÑанÑÐµÑ ÑÑиÑаннÑе даннÑе в памÑÑи, ÑÑÐ¾Ð±Ñ Ð·Ð°Ñем вÑдаÑÑ Ð¸Ñ
из памÑÑи на ÑледÑÑÑиÑ
пÑоÑ
одаÑ
.
ÐÑполнÑÑ Ð²Ð½ÐµÑние ÑоединениÑ, Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе вÑÑÑеÑиÑÑ ÑÐ·Ð»Ñ Ð¿Ð»Ð°Ð½Ð° Ñ Ð¿ÑиÑоединÑннÑми ÑÑловиÑми, как обÑÑнÑми «Filter», Ñак и «Join Filter» (ФилÑÑÑ ÑоединениÑ). УÑÐ»Ð¾Ð²Ð¸Ñ Join Filter ÑоÑмиÑÑÑÑÑÑ Ð¸Ð· пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ON Ð´Ð»Ñ Ð²Ð½ÐµÑнего ÑоединениÑ, Ñак ÑÑо еÑли ÑÑÑока не ÑдовлеÑвоÑÑÐµÑ ÑÑÐ»Ð¾Ð²Ð¸Ñ Join Filter, она вÑÑ Ð¶Ðµ вÑдаÑÑÑÑ ÐºÐ°Ðº ÑÑÑока, Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð½Ð°Ñ Ð·Ð½Ð°ÑениÑми NULL. ÐбÑÑное же ÑÑловие Filter пÑименÑеÑÑÑ Ð¿Ð¾Ñле пÑавил внеÑнего ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¸ поÑÑÐ¾Ð¼Ñ Ð¿Ð¾Ð»Ð½Ð¾ÑÑÑÑ Ð¸ÑклÑÑÐ°ÐµÑ ÑÑÑоки. Ðо внÑÑÑеннем Ñоединении оба ÑÑиÑ
ÑилÑÑÑа ÑабоÑаÑÑ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ð¾.
ÐÑли немного измениÑÑ Ð¸Ð·Ð±Ð¸ÑаÑелÑноÑÑÑ Ð·Ð°Ð¿ÑоÑа, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ полÑÑиÑÑ ÑовÑем дÑÑгой план ÑоединениÑ:
EXPLAIN SELECT *
FROM tenk1 t1, tenk2 t2
WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2;
QUERY PLAN
-------------------------------------------------------------------â-----------------------
Hash Join (cost=230.47..713.98 rows=101 width=488)
Hash Cond: (t2.unique2 = t1.unique2)
-> Seq Scan on tenk2 t2 (cost=0.00..445.00 rows=10000 width=244)
-> Hash (cost=229.20..229.20 rows=101 width=244)
-> Bitmap Heap Scan on tenk1 t1 (cost=5.07..229.20 rows=101 width=244)
Recheck Cond: (unique1 < 100)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0)
Index Cond: (unique1 < 100)
ÐдеÑÑ Ð¿Ð»Ð°Ð½Ð¸ÑовÑик вÑбиÑÐ°ÐµÑ Ñоединение по Ñ
еÑÑ, пÑи коÑоÑом ÑÑÑоки одной ÑаблиÑÑ Ð·Ð°Ð¿Ð¸ÑÑваÑÑÑÑ Ð² Ñ
еÑ-ÑаблиÑÑ Ð² памÑÑи, поÑле Ñего ÑканиÑÑеÑÑÑ Ð´ÑÑÐ³Ð°Ñ ÑаблиÑа и Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÐµÑ ÑÑÑоки пÑовеÑÑеÑÑÑ ÑооÑвеÑÑÑвие по Ñ
еÑ-ÑаблиÑе. ÐбÑаÑиÑе внимание, ÑÑо и здеÑÑ Ð¾ÑÑÑÑÐ¿Ñ Ð¾ÑÑажаÑÑ ÑÑÑÑкÑÑÑÑ Ð¿Ð»Ð°Ð½Ð°: ÑезÑлÑÑÐ°Ñ ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð±Ð¸Ñовой каÑÑÑ Ð¿Ð¾ tenk1 подаÑÑÑÑ Ð½Ð° вÑ
од ÑÐ·Ð»Ñ Hash, коÑоÑÑй конÑÑÑÑиÑÑÐµÑ Ñ
еÑ-ÑаблиÑÑ. ÐаÑем она пеÑедаÑÑÑÑ ÑÐ·Ð»Ñ Hash Join, коÑоÑÑй ÑиÑÐ°ÐµÑ ÑÑÑоки из Ñзла внеÑнего поÑомка и пÑовеÑÑÐµÑ Ð¸Ñ
по ÑÑой Ñ
еÑ-ÑаблиÑе.
ÐÑÑ Ð¾Ð´Ð¸Ð½ возможнÑй Ñип ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ â Ñоединение ÑлиÑнием:
EXPLAIN SELECT *
FROM tenk1 t1, onek t2
WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2;
QUERY PLAN
-------------------------------------------------------------------â-----------------------
Merge Join (cost=198.11..268.19 rows=10 width=488)
Merge Cond: (t1.unique2 = t2.unique2)
-> Index Scan using tenk1_unique2 on tenk1 t1 (cost=0.29..656.28 rows=101 width=244)
Filter: (unique1 < 100)
-> Sort (cost=197.83..200.33 rows=1000 width=244)
Sort Key: t2.unique2
-> Seq Scan on onek t2 (cost=0.00..148.00 rows=1000 width=244)
Соединение ÑлиÑнием ÑÑебÑеÑ, ÑÑÐ¾Ð±Ñ Ð²Ñ
однÑе даннÑе Ð´Ð»Ñ Ð½ÐµÐ³Ð¾ бÑли оÑÑоÑÑиÑÐ¾Ð²Ð°Ð½Ñ Ð¿Ð¾ клÑÑам ÑоединениÑ. Ð ÑÑом плане даннÑе tenk1 ÑоÑÑиÑÑÑÑÑÑ Ð¿Ð¾Ñле ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑа, пÑи коÑоÑом вÑе ÑÑÑоки пÑоÑмаÑÑиваÑÑÑÑ Ð² пÑавилÑном поÑÑдке, но ÑаблиÑÑ onek вÑгоднее оказÑваеÑÑÑ Ð¿Ð¾ÑледоваÑелÑно пÑоÑканиÑоваÑÑ Ð¸ оÑÑоÑÑиÑоваÑÑ, Ñак как в ÑÑой ÑаблиÑе нÑжно обÑабоÑаÑÑ Ð³Ð¾Ñаздо болÑÑе ÑÑÑок. (ÐоÑледоваÑелÑное ÑканиÑование и ÑоÑÑиÑовка ÑаÑÑо бÑÐ²Ð°ÐµÑ Ð±ÑÑÑÑее ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑа, когда нÑжно оÑÑоÑÑиÑоваÑÑ Ð¼Ð½Ð¾Ð³Ð¾ ÑÑÑок, Ñак как пÑи ÑканиÑовании по индекÑÑ Ð¾Ð±ÑаÑÐµÐ½Ð¸Ñ Ðº диÑÐºÑ Ð½Ðµ ÑпоÑÑдоÑенÑ.)
Ðдин из ÑпоÑобов поÑмоÑÑеÑÑ ÑазлиÑнÑе Ð¿Ð»Ð°Ð½Ñ â пÑинÑдиÑÑ Ð¿Ð»Ð°Ð½Ð¸ÑовÑик не ÑÑиÑаÑÑ Ð²ÑбÑаннÑÑ Ð¸Ð¼ ÑÑÑаÑÐµÐ³Ð¸Ñ Ñамой вÑгодной, иÑполÑзÑÑ Ñлаги, опиÑаннÑе в ÐодÑазделе 18.7.1. (ÐÑо полезнÑй, Ñ
оÑÑ Ð¸ гÑÑбÑй инÑÑÑÑменÑ. См. Ñакже Раздел 14.3.) ÐапÑимеÑ, еÑли Ð¼Ñ ÑбежденÑ, ÑÑо поÑледоваÑелÑное ÑканиÑование и ÑоÑÑиÑовка â не лÑÑÑий ÑпоÑоб обÑабоÑаÑÑ ÑаблиÑÑ onek в пÑедÑдÑÑем пÑимеÑе, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ попÑобоваÑÑ
SET enable_sort = off;
EXPLAIN SELECT *
FROM tenk1 t1, onek t2
WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2;
QUERY PLAN
-------------------------------------------------------------------â-----------------------
Merge Join (cost=0.56..292.65 rows=10 width=488)
Merge Cond: (t1.unique2 = t2.unique2)
-> Index Scan using tenk1_unique2 on tenk1 t1 (cost=0.29..656.28 rows=101 width=244)
Filter: (unique1 < 100)
-> Index Scan using onek_unique2 on onek t2 (cost=0.28..224.79 rows=1000 width=244)
Ðидно, ÑÑо планиÑовÑик ÑÑиÑÐ°ÐµÑ ÑоÑÑиÑÐ¾Ð²ÐºÑ onek Ñо ÑканиÑованием индекÑа пÑимеÑно на 12% доÑоже, Ñем поÑледоваÑелÑное ÑканиÑование и ÑоÑÑиÑовкÑ. ÐонеÑно, Ð¼Ð¾Ð¶ÐµÑ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½ÑÑÑ Ð²Ð¾Ð¿ÑÐ¾Ñ â а пÑавилÑно ли ÑÑо? ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ оÑвеÑиÑÑ Ð½Ð° него, иÑполÑзÑÑ Ð¾Ð¿Ð¸ÑаннÑÑ Ð½Ð¸Ð¶Ðµ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ EXPLAIN ANALYZE.
14.1.2. EXPLAIN ANALYZE #
ТоÑноÑÑÑ Ð¾Ñенок планиÑовÑика можно пÑовеÑиÑÑ, иÑполÑзÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ EXPLAIN Ñ Ð¿Ð°ÑамеÑÑом ANALYZE. С ÑÑим паÑамеÑÑом EXPLAIN на Ñамом деле вÑполнÑÐµÑ Ð·Ð°Ð¿ÑоÑ, а заÑем вÑÐ²Ð¾Ð´Ð¸Ñ ÑакÑиÑеÑкое ÑиÑло ÑÑÑок и вÑÐµÐ¼Ñ Ð²ÑполнениÑ, накопленное в каждом Ñзле плана, вмеÑÑе Ñ Ñеми же оÑенками, ÑÑо вÑдаÑÑ Ð¾Ð±ÑÑÐ½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° EXPLAIN. ÐапÑимеÑ, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ полÑÑиÑÑ Ð¿ÑимеÑно Ñакой ÑезÑлÑÑаÑ:
EXPLAIN ANALYZE SELECT *
FROM tenk1 t1, tenk2 t2
WHERE t1.unique1 < 10 AND t1.unique2 = t2.unique2;
QUERY PLAN
-------------------------------------------------------------------â--------------------------------------------------------------
Nested Loop (cost=4.65..118.62 rows=10 width=488) (actual time=0.128..0.377 rows=10 loops=1)
-> Bitmap Heap Scan on tenk1 t1 (cost=4.36..39.47 rows=10 width=244) (actual time=0.057..0.121 rows=10 loops=1)
Recheck Cond: (unique1 < 10)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..4.36 rows=10 width=0) (actual time=0.024..0.024 rows=10 loops=1)
Index Cond: (unique1 < 10)
-> Index Scan using tenk2_unique2 on tenk2 t2 (cost=0.29..7.91 rows=1 width=244) (actual time=0.021..0.022 rows=1 loops=10)
Index Cond: (unique2 = t1.unique2)
Planning time: 0.181 ms
Execution time: 0.501 ms
ÐамеÑÑÑе, ÑÑо знаÑÐµÐ½Ð¸Ñ Â«actual time» (ÑакÑиÑеÑкое вÑемÑ) пÑиводÑÑÑÑ Ð² миллиÑекÑндаÑ
, Ñогда как оÑенки cost (ÑÑоимоÑÑÑ) вÑÑажаÑÑÑÑ Ð² пÑоизволÑнÑÑ
единиÑаÑ
, Ñак ÑÑо они вÑÑд ли ÑовпадÑÑ. ÐбÑÑно важнее опÑеделиÑÑ, наÑколÑко пÑиблизиÑелÑÐ½Ð°Ñ Ð¾Ñенка ÑиÑла ÑÑÑок близка к дейÑÑвиÑелÑноÑÑи. Ð ÑÑом пÑимеÑе они в ÑоÑноÑÑи Ñовпали, но на пÑакÑике Ñак бÑÐ²Ð°ÐµÑ Ñедко.
РнекоÑоÑÑÑ
планаÑ
запÑоÑов некоÑоÑÑй внÑÑÑенний Ñзел Ð¼Ð¾Ð¶ÐµÑ Ð²ÑполнÑÑÑÑÑ Ð½ÐµÐ¾Ð´Ð½Ð¾ÐºÑаÑно. ÐапÑимеÑ, внÑÑÑеннее ÑканиÑование индекÑа бÑÐ´ÐµÑ Ð²ÑполнÑÑÑÑÑ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ внеÑней ÑÑÑоки во вложенном Ñикле веÑÑ
него ÑÑовнÑ. Ð ÑакиÑ
ÑлÑÑаÑÑ
знаÑение loops (ÑиклÑ) показÑваеÑ, ÑколÑко вÑего Ñаз вÑполнÑлÑÑ ÑÑÐ¾Ñ Ñзел, а ÑакÑиÑеÑкое вÑÐµÐ¼Ñ Ð¸ ÑиÑло ÑÑÑок вÑÑиÑлÑеÑÑÑ ÐºÐ°Ðº ÑÑеднее по вÑем иÑеÑаÑиÑм. ÐÑо делаеÑÑÑ Ð´Ð»Ñ Ñого, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑеннÑе знаÑÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ бÑло ÑÑавниÑÑ Ñ Ð²ÑводимÑми пÑиблизиÑелÑнÑми оÑенками. ЧÑÐ¾Ð±Ñ Ð¿Ð¾Ð»ÑÑиÑÑ Ð¾Ð±Ñее вÑемÑ, заÑÑаÑенное на вÑполнение Ñзла, вÑÐµÐ¼Ñ Ð¾Ð´Ð½Ð¾Ð¹ иÑеÑаÑии нÑжно ÑмножиÑÑ Ð½Ð° знаÑение loops. Рпоказанном вÑÑе пÑимеÑе Ð¼Ñ Ð¿Ð¾ÑÑаÑили в обÑей ÑложноÑÑи 0.220 Ð¼Ñ Ð½Ð° ÑканиÑование индекÑа в tenk2.
Ð ÑÑде ÑлÑÑаев EXPLAIN ANALYZE вÑÐ²Ð¾Ð´Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ ÑÑаÑиÑÑÐ¸ÐºÑ Ð¿Ð¾ вÑполнениÑ, вклÑÑаÑÑÑÑ Ð½Ðµ ÑолÑко вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñзлов и ÑиÑло ÑÑÑок. ÐÐ»Ñ Ñзлов Sort и Hash, напÑÐ¸Ð¼ÐµÑ Ð²ÑводиÑÑÑ ÑледÑÑÑÐ°Ñ Ð¸Ð½ÑоÑмаÑиÑ:
EXPLAIN ANALYZE SELECT *
FROM tenk1 t1, tenk2 t2
WHERE t1.unique1 < 100 AND t1.unique2 = t2.unique2 ORDER BY t1.fivethous;
QUERY PLAN
-------------------------------------------------------------------â-------------------------------------------------------------------â------
Sort (cost=717.34..717.59 rows=101 width=488) (actual time=7.761..7.774 rows=100 loops=1)
Sort Key: t1.fivethous
Sort Method: quicksort Memory: 77kB
-> Hash Join (cost=230.47..713.98 rows=101 width=488) (actual time=0.711..7.427 rows=100 loops=1)
Hash Cond: (t2.unique2 = t1.unique2)
-> Seq Scan on tenk2 t2 (cost=0.00..445.00 rows=10000 width=244) (actual time=0.007..2.583 rows=10000 loops=1)
-> Hash (cost=229.20..229.20 rows=101 width=244) (actual time=0.659..0.659 rows=100 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 28kB
-> Bitmap Heap Scan on tenk1 t1 (cost=5.07..229.20 rows=101 width=244) (actual time=0.080..0.526 rows=100 loops=1)
Recheck Cond: (unique1 < 100)
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0) (actual time=0.049..0.049 rows=100 loops=1)
Index Cond: (unique1 < 100)
Planning time: 0.194 ms
Execution time: 8.008 ms
ÐÐ»Ñ Ñзла Sort показÑваеÑÑÑ Ð¸ÑполÑзованнÑй меÑод и меÑÑо ÑоÑÑиÑовки (в памÑÑи или на диÑке), а Ñакже задейÑÑвованнÑй обÑÑм памÑÑи. ÐÐ»Ñ Ñзла Hash вÑводиÑÑÑ ÑиÑло гÑÑпп и пакеÑов Ñ ÐµÑа, а Ñакже макÑималÑнÑй обÑÑм, коÑоÑÑй занÑла в памÑÑи Ñ ÐµÑ-ÑаблиÑа. (ÐÑли ÑиÑло пакеÑов болÑÑе одного, ÑаÑÑÑ Ñ ÐµÑ-ÑаблиÑÑ Ð±ÑÐ´ÐµÑ Ð²ÑгÑÑжаÑÑÑÑ Ð½Ð° диÑк и занимаÑÑ ÐºÐ°ÐºÐ¾Ðµ-Ñо пÑоÑÑÑанÑÑво, но его обÑÑм здеÑÑ Ð½Ðµ показÑваеÑÑÑ.)
ÐÑÑÐ³Ð°Ñ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð°Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑÐ½Ð°Ñ Ð¸Ð½ÑоÑмаÑÐ¸Ñ â ÑиÑло ÑÑÑок, ÑдалÑннÑÑ ÑÑловием ÑилÑÑÑа:
EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE ten < 7;
QUERY PLAN
-------------------------------------------------------------------â--------------------------------------
Seq Scan on tenk1 (cost=0.00..483.00 rows=7000 width=244) (actual time=0.016..5.107 rows=7000 loops=1)
Filter: (ten < 7)
Rows Removed by Filter: 3000
Planning time: 0.083 ms
Execution time: 5.905 ms
ÐÑи знаÑÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑÑ Ð±ÑÑÑ Ð¾Ñобенно ÑÐµÐ½Ð½Ñ Ð´Ð»Ñ ÑÑловий ÑилÑÑÑа, пÑименÑннÑÑ Ðº Ñзлам ÑоединениÑ. СÑÑока «Rows Removed» вÑводиÑÑÑ, ÑолÑко когда ÑÑловие ÑилÑÑÑа оÑбÑаÑÑÐ²Ð°ÐµÑ Ð¼Ð¸Ð½Ð¸Ð¼Ñм Ð¾Ð´Ð½Ñ Ð¿ÑоÑканиÑованнÑÑ ÑÑÑÐ¾ÐºÑ Ð¸Ð»Ð¸ поÑенÑиалÑнÑÑ Ð¿Ð°ÑÑ ÑоединениÑ, еÑли ÑÑо Ñзел ÑоединениÑ.
ÐÐ¾Ñ Ð¾Ð¶ÑÑ ÑиÑÑаÑÐ¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ наблÑдаÑÑ Ð¿Ñи ÑканиÑовании «неÑоÑного» индекÑа. ÐапÑимеÑ, ÑаÑÑмоÑÑим ÑÑÐ¾Ñ Ð¿Ð»Ð°Ð½ поиÑка многоÑголÑников, ÑодеÑжаÑÐ¸Ñ ÑказаннÑÑ ÑоÑкÑ:
EXPLAIN ANALYZE SELECT * FROM polygon_tbl WHERE f1 @> polygon '(0.5,2.0)';
QUERY PLAN
-------------------------------------------------------------------â-----------------------------------
Seq Scan on polygon_tbl (cost=0.00..1.05 rows=1 width=32) (actual time=0.044..0.044 rows=0 loops=1)
Filter: (f1 @> '((0.5,2))'::polygon)
Rows Removed by Filter: 4
Planning time: 0.040 ms
Execution time: 0.083 ms
ÐланиÑовÑик Ð¿Ð¾Ð»Ð°Ð³Ð°ÐµÑ (и вполне ÑпÑаведливо), ÑÑо ÑаблиÑа ÑлиÑком мала Ð´Ð»Ñ ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ индекÑÑ, поÑÑÐ¾Ð¼Ñ Ð¾Ð½ вÑбиÑÐ°ÐµÑ Ð¿Ð¾ÑледоваÑелÑное ÑканиÑование, пÑи коÑоÑом вÑе ÑÑÑоки оÑбÑаÑÑваÑÑÑÑ ÑÑловием ÑилÑÑÑа. Ðо еÑли Ð¼Ñ Ð¿ÑинÑдим его вÑбÑаÑÑ ÑканиÑование по индекÑÑ, Ð¼Ñ Ð¿Ð¾Ð»ÑÑим:
SET enable_seqscan TO off;
EXPLAIN ANALYZE SELECT * FROM polygon_tbl WHERE f1 @> polygon '(0.5,2.0)';
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
Index Scan using gpolygonind on polygon_tbl (cost=0.13..8.15 rows=1 width=32) (actual time=0.062..0.062 rows=0 loops=1)
Index Cond: (f1 @> '((0.5,2))'::polygon)
Rows Removed by Index Recheck: 1
Planning time: 0.034 ms
Execution time: 0.144 ms
ÐдеÑÑ Ð¼Ñ Ð²Ð¸Ð´Ð¸Ð¼, ÑÑо Ð¸Ð½Ð´ÐµÐºÑ Ð²ÐµÑнÑл Ð¾Ð´Ð½Ñ Ð¿Ð¾ÑенÑиалÑно Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑÑÑ ÑÑÑокÑ, но заÑем она бÑла оÑбÑоÑена пÑи пеÑепÑовеÑке ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑа. ÐÑо обÑÑÑнÑеÑÑÑ Ñем, ÑÑо Ð¸Ð½Ð´ÐµÐºÑ GiST ÑвлÑеÑÑÑ Â«Ð½ÐµÑоÑнÑм» Ð´Ð»Ñ Ð¿ÑовеÑок вклÑÑений многоÑголÑников: ÑакÑиÑеÑки он возвÑаÑÐ°ÐµÑ ÑÑÑоки Ñ Ð¼Ð½Ð¾Ð³Ð¾ÑголÑниками, пеÑекÑÑваÑÑими ÑоÑÐºÑ Ð¿Ð¾ кооÑдинаÑам, а заÑем Ð´Ð»Ñ ÑÑÐ¸Ñ ÑÑÑок нÑжно вÑполнÑÑÑ ÑоÑнÑÑ Ð¿ÑовеÑкÑ.
EXPLAIN пÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ Ð¿Ð°ÑамеÑÑ BUFFERS (коÑоÑÑй Ñакже можно пÑименÑÑÑ Ñ ANALYZE), вклÑÑаÑÑий еÑÑ Ð±Ð¾Ð»ÐµÐµ подÑобнÑÑ ÑÑаÑиÑÑÐ¸ÐºÑ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа:
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000;
QUERY PLAN
-------------------------------------------------------------------â--------------------------------------------------------------
Bitmap Heap Scan on tenk1 (cost=25.08..60.21 rows=10 width=244) (actual time=0.323..0.342 rows=10 loops=1)
Recheck Cond: ((unique1 < 100) AND (unique2 > 9000))
Buffers: shared hit=15
-> BitmapAnd (cost=25.08..25.08 rows=10 width=0) (actual time=0.309..0.309 rows=0 loops=1)
Buffers: shared hit=7
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.04 rows=101 width=0) (actual time=0.043..0.043 rows=100 loops=1)
Index Cond: (unique1 < 100)
Buffers: shared hit=2
-> Bitmap Index Scan on tenk1_unique2 (cost=0.00..19.78 rows=999 width=0) (actual time=0.227..0.227 rows=999 loops=1)
Index Cond: (unique2 > 9000)
Buffers: shared hit=5
Planning time: 0.088 ms
Execution time: 0.423 ms
ÐнаÑениÑ, коÑоÑÑе вÑводÑÑÑÑ Ñ Ð¿Ð°ÑамеÑÑом BUFFERS, помогаÑÑ Ð¿Ð¾Ð½ÑÑÑ, на какие ÑаÑÑи запÑоÑа пÑиÑ
одиÑÑÑ Ð±Ð¾Ð»ÑÑинÑÑво опеÑаÑий ввода-вÑвода.
Ðе забÑвайÑе, ÑÑо EXPLAIN ANALYZE дейÑÑвиÑелÑно вÑполнÑÐµÑ Ð·Ð°Ð¿ÑоÑ, Ñ
оÑÑ ÐµÐ³Ð¾ ÑезÑлÑÑаÑÑ Ð¼Ð¾Ð³ÑÑ Ð½Ðµ показÑваÑÑÑÑ, а заменÑÑÑÑÑ Ð²Ñводом ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ EXPLAIN. ÐоÑÑÐ¾Ð¼Ñ Ð¿Ñи Ñаком анализе Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñ Ð¿Ð¾Ð±Ð¾ÑнÑе ÑÑÑекÑÑ. ÐÑли Ð²Ñ Ñ
оÑиÑе пÑоанализиÑоваÑÑ Ð·Ð°Ð¿ÑоÑ, изменÑÑÑий даннÑе, но пÑи ÑÑом ÑоÑ
ÑаниÑÑ Ð¿Ñежние даннÑе ÑаблиÑÑ, Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе оÑкаÑиÑÑ ÑÑанзакÑÐ¸Ñ Ð¿Ð¾Ñле запÑоÑа:
BEGIN;
EXPLAIN ANALYZE UPDATE tenk1 SET hundred = hundred + 1 WHERE unique1 < 100;
QUERY PLAN
-------------------------------------------------------------------â-------------------------------------------------------------
Update on tenk1 (cost=5.08..230.08 rows=0 width=0) (actual time=3.791..3.792 rows=0 loops=1)
-> Bitmap Heap Scan on tenk1 (cost=5.08..230.08 rows=102 width=10) (actual time=0.069..0.513 rows=100 loops=1)
Recheck Cond: (unique1 < 100)
Heap Blocks: exact=90
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..5.05 rows=102 width=0) (actual time=0.036..0.037 rows=300 loops=1)
Index Cond: (unique1 < 100)
Planning Time: 0.113 ms
Execution Time: 3.850 ms
ROLLBACK;
Ðак показано в ÑÑом пÑимеÑе, когда вÑполнÑеÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° INSERT, UPDATE, DELETE или MERGE, ÑобÑÑвенно изменение даннÑÑ
в ÑаблиÑе пÑоиÑÑ
Ð¾Ð´Ð¸Ñ Ð² Ñзле веÑÑ
него ÑÑÐ¾Ð²Ð½Ñ Insert, Update, Delete или Merge. Ð£Ð·Ð»Ñ Ð¿Ð»Ð°Ð½Ð° более низкиÑ
ÑÑовней вÑполнÑÑÑ ÑабоÑÑ Ð¿Ð¾ наÑ
Ð¾Ð¶Ð´ÐµÐ½Ð¸Ñ ÑÑаÑÑÑ
ÑÑÑок и/или вÑÑиÑÐ»ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²ÑÑ
даннÑÑ
. ÐоÑÑÐ¾Ð¼Ñ Ð²Ð²ÐµÑÑ
Ñ Ð¼Ñ Ð²Ð¸Ð´Ð¸Ð¼ ÑÐ¾Ñ Ð¶Ðµ Ñип ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð±Ð¸Ñовой каÑÑÑ, ÑÑо и ÑанÑÑе, ÑолÑко ÑепеÑÑ ÐµÐ³Ð¾ вÑвод подаÑÑÑÑ ÑÐ·Ð»Ñ Update, коÑоÑÑй ÑоÑ
ÑанÑÐµÑ Ð¸Ð·Ð¼ÐµÐ½ÑннÑе ÑÑÑоки. СÑÐ¾Ð¸Ñ Ð¾ÑмеÑиÑÑ, ÑÑо Ñзел, изменÑÑÑий даннÑе, Ð¼Ð¾Ð¶ÐµÑ Ð²ÑполнÑÑÑÑÑ Ð·Ð½Ð°ÑиÑелÑное вÑÐµÐ¼Ñ (в данном ÑлÑÑае ÑÑо ÑоÑÑавлÑÐµÑ Ð»ÑвинÑÑ ÑаÑÑÑ Ð²Ñего вÑемени), но планиÑовÑик не ÑÑиÑÑÐ²Ð°ÐµÑ ÑÑÑ ÑабоÑÑ Ð² оÑенке обÑей ÑÑоимоÑÑи. ÐÑо ÑвÑзано Ñ Ñем, ÑÑо ÑÑа ÑабоÑа бÑÐ´ÐµÑ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ð¾Ð¹ пÑи лÑбом пÑавилÑном плане запÑоÑа, и поÑÑÐ¾Ð¼Ñ Ð½Ð° вÑÐ±Ð¾Ñ Ð¿Ð»Ð°Ð½Ð° она не влиÑеÑ.
Ðогда команда UPDATE, DELETE или MERGE Ð¸Ð¼ÐµÐµÑ Ð´ÐµÐ»Ð¾ Ñ Ð¸ÐµÑаÑÑ
ией наÑледованиÑ, вÑвод Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ñаким:
EXPLAIN UPDATE parent SET f2 = f2 + 1 WHERE f1 = 101;
QUERY PLAN
-------------------------------------------------------------------â-----------------------------------
Update on parent (cost=0.00..24.59 rows=0 width=0)
Update on parent parent_1
Update on child1 parent_2
Update on child2 parent_3
Update on child3 parent_4
-> Result (cost=0.00..24.59 rows=4 width=14)
-> Append (cost=0.00..24.54 rows=4 width=14)
-> Seq Scan on parent parent_1 (cost=0.00..0.00 rows=1 width=14)
Filter: (f1 = 101)
-> Index Scan using child1_pkey on child1 parent_2 (cost=0.15..8.17 rows=1 width=14)
Index Cond: (f1 = 101)
-> Index Scan using child2_pkey on child2 parent_3 (cost=0.15..8.17 rows=1 width=14)
Index Cond: (f1 = 101)
-> Index Scan using child3_pkey on child3 parent_4 (cost=0.15..8.17 rows=1 width=14)
Index Cond: (f1 = 101)
Ð ÑÑом пÑимеÑе ÑÐ·Ð»Ñ Update помимо изнаÑалÑно ÑпомÑнÑÑой в запÑоÑе ÑодиÑелÑÑкой ÑаблиÑÑ Ð½Ñжно обÑабоÑаÑÑ ÐµÑÑ ÑÑи доÑеÑние ÑаблиÑÑ. ÐоÑÑÐ¾Ð¼Ñ ÑоÑмиÑÑÑÑÑÑ ÑеÑÑÑе плана ÑканиÑованиÑ, по Ð¾Ð´Ð½Ð¾Ð¼Ñ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑаблиÑÑ. ЯÑноÑÑи Ñади Ð´Ð»Ñ Ñзла Update добавлÑеÑÑÑ Ð¿ÑимеÑание, показÑваÑÑее, какие именно ÑаблиÑÑ Ð±ÑдÑÑ Ð¸Ð·Ð¼ÐµÐ½ÑÑÑÑÑ, в Ñом же поÑÑдке, в каком они идÑÑ Ð² ÑооÑвеÑÑÑвÑÑÑÐ¸Ñ Ð²Ð½ÑÑÑÐµÐ½Ð½Ð¸Ñ Ð¿Ð»Ð°Ð½Ð°Ñ .
Ðод заголовком Planning time (ÐÑÐµÐ¼Ñ Ð¿Ð»Ð°Ð½Ð¸ÑованиÑ) команда EXPLAIN ANALYZE вÑÐ²Ð¾Ð´Ð¸Ñ Ð²ÑемÑ, заÑÑаÑенное на поÑÑÑоение плана запÑоÑа из ÑазобÑанного запÑоÑа и его опÑимизаÑиÑ. ÐÑÐµÐ¼Ñ ÑобÑÑвенно ÑазбоÑа или пеÑезапиÑи запÑоÑа в него не вклÑÑаеÑÑÑ.
ÐнаÑение Execution time (ÐÑÐµÐ¼Ñ Ð²ÑполнениÑ), вÑводимое командой EXPLAIN ANALYZE, вклÑÑÐ°ÐµÑ Ð¿ÑодолжиÑелÑноÑÑÑ Ð·Ð°Ð¿ÑÑка и оÑÑановки иÑполниÑÐµÐ»Ñ Ð·Ð°Ð¿ÑоÑа, а Ñакже вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð²ÑеÑ
ÑÑабоÑавÑиÑ
ÑÑиггеÑов, но не вклÑÑÐ°ÐµÑ Ð²ÑÐµÐ¼Ñ ÑазбоÑа, пеÑезапиÑи и планиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа. ÐÑемÑ, поÑÑаÑенное на вÑполнение ÑÑиггеÑов BEFORE (еÑли Ñакие имеÑÑÑÑ) вклÑÑаеÑÑÑ Ð²Ð¾ вÑÐµÐ¼Ñ ÑооÑвеÑÑÑвÑÑÑиÑ
Ñзлов Insert, Update или Delete node; но вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÑÑиггеÑов AFTER не ÑÑиÑÑваеÑÑÑ, Ñак как ÑÑиггеÑÑ AFTER ÑÑабаÑÑваÑÑ Ð¿Ð¾Ñле вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð²Ñего плана. ÐбÑее вÑемÑ, пÑоведÑнное в каждом ÑÑиггеÑе (BEFORE или AFTER), Ñакже вÑводиÑÑÑ Ð¾ÑделÑно. ÐамеÑÑÑе, ÑÑо ÑÑиггеÑÑ Ð¾ÑложеннÑÑ
огÑаниÑений вÑполнÑÑÑÑÑ ÑолÑко в конÑе ÑÑанзакÑии, Ñак ÑÑо вÑÐµÐ¼Ñ Ð¸Ñ
вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ EXPLAIN ANALYZE не ÑÑиÑÑваеÑ.
14.1.3. ÐгÑаниÑÐµÐ½Ð¸Ñ #
ÐÑÐµÐ¼Ñ Ð²ÑполнениÑ, измеÑенное командой EXPLAIN ANALYZE, Ð¼Ð¾Ð¶ÐµÑ Ð·Ð½Ð°ÑиÑелÑно оÑлиÑаÑÑÑÑ Ð¾Ñ Ð²Ñемени вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñого же запÑоÑа в обÑÑном Ñежиме. Ð¢Ð¾Ð¼Ñ ÐµÑÑÑ Ð´Ð²Ðµ оÑновнÑÑ
пÑиÑинÑ. Ðо-пеÑвÑÑ
, Ñак как пÑи анализе никакие ÑÑÑоки ÑезÑлÑÑаÑа не пеÑедаÑÑÑÑ ÐºÐ»Ð¸ÐµÐ½ÑÑ, вÑÐµÐ¼Ñ Ð²Ð²Ð¾Ð´Ð°-вÑвода и пеÑедаÑи по ÑеÑи не ÑÑиÑÑваеÑÑÑ. Ðо-вÑоÑÑÑ
, Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑÑÑеÑÑвенной дополниÑелÑÐ½Ð°Ñ Ð½Ð°Ð³ÑÑзка, ÑвÑÐ·Ð°Ð½Ð½Ð°Ñ Ñ ÑÑнкÑиÑми измеÑений EXPLAIN ANALYZE, оÑобенно в ÑиÑÑемаÑ
, где вÑзов gettimeofday() вÑполнÑеÑÑÑ Ð¼ÐµÐ´Ð»ÐµÐ½Ð½Ð¾. ÐÐ»Ñ Ð¸Ð·Ð¼ÐµÑÐµÐ½Ð¸Ñ ÑÑой нагÑÑзки Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе воÑполÑзоваÑÑÑÑ ÑÑилиÑой pg_test_timing.
РезÑлÑÑаÑÑ EXPLAIN не ÑледÑÐµÑ ÑаÑпÑоÑÑÑанÑÑÑ Ð½Ð° ÑиÑÑаÑии, знаÑиÑелÑно оÑлиÑаÑÑиеÑÑ Ð¾Ñ ÑеÑ
, в коÑоÑÑÑ
Ð²Ñ Ð¿ÑоводиÑе ÑеÑÑиÑование. Ð ÑаÑÑноÑÑи, не ÑледÑÐµÑ Ð¿Ð¾Ð»Ð°Ð³Ð°ÑÑ, ÑÑо вÑводÑ, полÑÑеннÑе Ð´Ð»Ñ Ð¸Ð³ÑÑÑеÑной ÑаблиÑÑ, бÑдÑÑ Ð¿ÑÐ¸Ð¼ÐµÐ½Ð¸Ð¼Ñ Ð¸ Ð´Ð»Ñ Ð½Ð°ÑÑоÑÑиÑ
болÑÑиÑ
ÑаблиÑ. ÐÑенки ÑÑоимоÑÑи Ð½ÐµÐ»Ð¸Ð½ÐµÐ¹Ð½Ñ Ð¸ планиÑовÑик Ð¼Ð¾Ð¶ÐµÑ Ð²ÑбиÑаÑÑ ÑазнÑе Ð¿Ð»Ð°Ð½Ñ Ð² завиÑимоÑÑи Ð¾Ñ ÑазмеÑа ÑаблиÑÑ. ÐапÑимеÑ, в кÑайнем ÑлÑÑае вÑÑ ÑаблиÑа Ð¼Ð¾Ð¶ÐµÑ ÑмеÑÑиÑÑÑÑ Ð² Ð¾Ð´Ð½Ñ ÑÑÑаниÑÑ Ð´Ð¸Ñка, и Ñогда Ð²Ñ Ð¿Ð¾ÑÑи навеÑнÑка полÑÑиÑе план поÑледоваÑелÑного ÑканиÑованиÑ, незавиÑимо Ð¾Ñ Ñого, еÑÑÑ Ñ Ð½ÐµÑ Ð¸ индекÑÑ Ð¸Ð»Ð¸ неÑ. ÐланиÑовÑик понимаеÑ, ÑÑо Ð´Ð»Ñ Ð¾Ð±ÑабоÑки ÑаблиÑÑ ÐµÐ¼Ñ Ð² лÑбом ÑлÑÑае поÑÑебÑеÑÑÑ Ð¿ÑоÑиÑаÑÑ Ð¾Ð´Ð½Ñ ÑÑÑаниÑÑ, Ñак ÑÑо Ð½ÐµÑ Ð½Ð¸ÐºÐ°ÐºÐ¾Ð³Ð¾ ÑмÑÑла обÑаÑаÑÑÑÑ Ðº еÑÑ Ð¾Ð´Ð½Ð¾Ð¹ ÑÑÑаниÑе за индекÑом. (ÐÑ Ð½Ð°Ð±Ð»Ñдали ÑÑо в показанном вÑÑе пÑимеÑе Ñ polygon_tbl.)
ÐÑваеÑ, ÑÑо ÑакÑиÑеÑкое и пÑиближÑнно оÑенÑнное знаÑÐµÐ½Ð¸Ñ Ð½Ðµ ÑовпадаÑÑ, но в ÑÑом Ð½ÐµÑ Ð½Ð¸Ñего плоÑ
ого. ÐапÑимеÑ, ÑÑо возможно, когда вÑполнение плана Ñзла пÑекÑаÑаеÑÑÑ Ð¿ÑеждевÑеменно из-за ÑÐºÐ°Ð·Ð°Ð½Ð¸Ñ LIMIT или подобного ÑÑÑекÑа. ÐапÑимеÑ, Ð´Ð»Ñ Ð·Ð°Ð¿ÑоÑа Ñ LIMIT, коÑоÑÑй Ð¼Ñ Ð¿Ñобовали ÑанÑÑе:
EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 LIMIT 2;
QUERY PLAN
-------------------------------------------------------------------â------------------------------------------------------------
Limit (cost=0.29..14.71 rows=2 width=244) (actual time=0.177..0.249 rows=2 loops=1)
-> Index Scan using tenk1_unique2 on tenk1 (cost=0.29..72.42 rows=10 width=244) (actual time=0.174..0.244 rows=2 loops=1)
Index Cond: (unique2 > 9000)
Filter: (unique1 < 100)
Rows Removed by Filter: 287
Planning time: 0.096 ms
Execution time: 0.336 ms
ÐÑенки ÑÑоимоÑÑи и ÑиÑла ÑÑÑок Ð´Ð»Ñ Ñзла Index Scan показÑваÑÑÑÑ Ð² пÑедположении, ÑÑо ÑÑÐ¾Ñ Ñзел бÑÐ´ÐµÑ Ð²ÑполнÑÑÑÑÑ Ð´Ð¾ конÑа. Ðо в дейÑÑвиÑелÑноÑÑи Ñзел Limit пÑекÑаÑил запÑаÑиваÑÑ ÑÑÑоки, как ÑолÑко полÑÑил пеÑвÑе две, Ñак ÑÑо ÑакÑиÑеÑкое ÑиÑло ÑÑÑок Ñавно 2 и вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа бÑÐ´ÐµÑ Ð¼ÐµÐ½ÑÑе, Ñем ÑаÑÑÑиÑал планиÑовÑик. Ðо ÑÑо не оÑибка, а пÑоÑÑо ÑледÑÑвие Ñого, ÑÑо оÑенÑннÑе и ÑакÑиÑеÑкие знаÑÐµÐ½Ð¸Ñ Ð²ÑводÑÑÑÑ Ð¿Ð¾-ÑазномÑ.
Ð¡Ð¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ ÑлиÑнием Ñакже имеÑÑ Ñвои оÑобенноÑÑи, коÑоÑÑе могÑÑ Ð²Ð²ÐµÑÑи в заблÑждение. Соединение ÑлиÑнием пÑекÑаÑÐ¸Ñ ÑиÑаÑÑ Ð¾Ð´Ð¸Ð½ иÑÑоÑник даннÑÑ
, еÑли вÑоÑой бÑÐ´ÐµÑ Ð¿ÑоÑиÑан до конÑа, а ÑледÑÑÑее знаÑение клÑÑа в пеÑвом болÑÑе поÑледнего знаÑÐµÐ½Ð¸Ñ Ð²Ð¾ вÑоÑом. Ð ÑÑом ÑлÑÑае Ð¿Ð°Ñ ÑÑÑок болÑÑе не бÑдеÑ, Ñак ÑÑо ÑканиÑоваÑÑ Ð¿ÐµÑвÑй иÑÑоÑник далÑÑе Ð½ÐµÑ ÑмÑÑла. Ð ÑезÑлÑÑаÑе бÑдÑÑ Ð¿ÑоÑиÑÐ°Ð½Ñ Ð½Ðµ вÑе ÑÑÑоки одного поÑомка и Ð²Ñ Ð¿Ð¾Ð»ÑÑиÑе ÑÐ¾Ñ Ð¶Ðµ ÑÑÑекÑ, ÑÑо и Ñ LIMIT. ÐÑоме Ñого, еÑли внеÑний (пеÑвÑй) поÑомок ÑодеÑÐ¶Ð¸Ñ ÑÑÑоки Ñ Ð¿Ð¾Ð²ÑоÑÑÑÑимиÑÑ Ð·Ð½Ð°ÑениÑми клÑÑа, внÑÑÑенний (вÑоÑой) поÑомок ÑдвинеÑÑÑ Ð½Ð°Ð·Ð°Ð´ и повÑоÑно вÑдаÑÑ ÑÑÑоки Ð´Ð»Ñ ÑÑого знаÑÐµÐ½Ð¸Ñ ÐºÐ»ÑÑа. EXPLAIN ANALYZE ÑÑиÑÐ°ÐµÑ ÑÑи повÑоÑÑÑÑиеÑÑ ÑÑÑоки, как еÑли Ð±Ñ ÑÑо дейÑÑвиÑелÑно бÑли дополниÑелÑнÑе ÑÑÑоки внÑÑÑеннего иÑÑоÑника. Ðогда во внеÑнем Ñзле много ÑакиÑ
повÑоÑений клÑÑей, ÑакÑиÑеÑкое ÑиÑло ÑÑÑок, подÑÑиÑанное Ð´Ð»Ñ Ð²Ð½ÑÑÑеннего Ñзла, Ð¼Ð¾Ð¶ÐµÑ Ð·Ð½Ð°ÑиÑелÑно пÑевÑÑаÑÑ ÑиÑло ÑÑÑок в ÑооÑвеÑÑÑвÑÑÑей ÑаблиÑе.
ÐÐ»Ñ Ñзлов BitmapAnd (ÐогиÑеÑкое пÑоизведение биÑовÑÑ ÐºÐ°ÑÑ) и BitmapOr (ÐогиÑеÑкое Ñложение биÑовÑÑ ÐºÐ°ÑÑ) ÑакÑиÑеÑкое ÑиÑло ÑÑÑок вÑегда Ñавно 0 из-за огÑаниÑений ÑеализаÑии.
ÐбÑÑно EXPLAIN вÑÐ²Ð¾Ð´Ð¸Ñ Ð¿Ð¾Ð´ÑобноÑÑи Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñзла плана, ÑгенеÑиÑованного планиÑовÑиком. Ðднако бÑваÑÑ ÑиÑÑаÑии, когда иÑполниÑÐµÐ»Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð¿ÑеделиÑÑ, ÑÑо некоÑоÑÑе ÑÐ·Ð»Ñ Ð½Ðµ нÑжно вÑполнÑÑÑ, Ñак как они не могÑÑ Ð²ÑдаÑÑ Ð½Ð¸ÐºÐ°ÐºÐ¸Ðµ ÑÑÑоки, Ñ ÑÑÑÑом знаÑений паÑамеÑÑов, ÑÑавÑиÑ
извеÑÑнÑми Ñже поÑле планиÑованиÑ. (РнаÑÑоÑÑее вÑÐµÐ¼Ñ ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑоизойÑи ÑолÑко Ñ Ð´Ð¾ÑеÑними Ñзлами Append или MergeAppend, ÑканиÑÑÑÑими ÑекÑиониÑованнÑÑ ÑаблиÑÑ.) Ð ÑакиÑ
ÑиÑÑаÑиÑÑ
ÑÑи ÑÐ·Ð»Ñ Ð¿Ð»Ð°Ð½Ð° не попадаÑÑ Ð² вÑвод EXPLAIN, а в плане поÑвлÑеÑÑÑ Ð·Ð°Ð¿Ð¸ÑÑ Subplans Removed: (Ðодпланов Ñдалено: N).N