EXPLAIN
EXPLAIN â показаÑÑ Ð¿Ð»Ð°Ð½ вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑаÑоÑа
СинÑакÑиÑ
EXPLAIN [ (паÑамеÑÑ[, ...] ) ]опеÑаÑоÑEXPLAIN [ ANALYZE ] [ VERBOSE ]опеÑаÑоÑÐдеÑÑ Ð´Ð¾Ð¿ÑÑкаеÑÑÑпаÑамеÑÑ: ANALYZE [boolean] VERBOSE [boolean] COSTS [boolean] SETTINGS [boolean] GENERIC_PLAN [boolean] BUFFERS [boolean] WAL [boolean] TIMING [boolean] SUMMARY [boolean] FORMAT { TEXT | XML | JSON | YAML }
ÐпиÑание
ÐÑа команда вÑÐ²Ð¾Ð´Ð¸Ñ Ð¿Ð»Ð°Ð½ вÑполнениÑ, генеÑиÑÑемÑй планиÑовÑиком PostgreSQL Ð´Ð»Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ опеÑаÑоÑа. Ðлан вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾ÐºÐ°Ð·ÑваеÑ, как бÑдÑÑ ÑканиÑоваÑÑÑÑ ÑаблиÑÑ, заÑÑагиваемÑе опеÑаÑоÑом â пÑоÑÑо поÑледоваÑелÑно, по индекÑÑ Ð¸ Ñ. д. â а еÑли запÑÐ¾Ñ ÑвÑзÑÐ²Ð°ÐµÑ Ð½ÐµÑколÑко ÑаблиÑ, какой алгоÑиÑм ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð±ÑÐ´ÐµÑ Ð²ÑбÑан Ð´Ð»Ñ Ð¾Ð±ÑÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ ÑÑиÑаннÑÑ Ð¸Ð· Ð½Ð¸Ñ ÑÑÑок.
ÐаиболÑÑий инÑеÑÐµÑ Ð² вÑводимой инÑоÑмаÑии пÑедÑÑавлÑÐµÑ Ð¾Ð¶Ð¸Ð´Ð°ÐµÐ¼Ð°Ñ ÑÑоимоÑÑÑ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑаÑоÑа, коÑоÑÐ°Ñ Ð¿Ð¾ÐºÐ°Ð·ÑваеÑ, ÑколÑко, по Ð¼Ð½ÐµÐ½Ð¸Ñ Ð¿Ð»Ð°Ð½Ð¸ÑовÑика, бÑÐ´ÐµÑ Ð²ÑполнÑÑÑÑÑ ÑÑÐ¾Ñ Ð¾Ð¿ÐµÑаÑÐ¾Ñ (ÑÑо знаÑение измеÑÑеÑÑÑ Ð² единиÑаÑ
ÑÑоимоÑÑи, коÑоÑÑе не имеÑÑ ÑоÑного опÑеделениÑ, но обÑÑно ÑÑо обÑаÑение к ÑÑÑаниÑе на диÑке). ФакÑиÑеÑки вÑводÑÑÑÑ Ð´Ð²Ð° ÑиÑла: ÑÑоимоÑÑÑ Ð·Ð°Ð¿ÑÑка до вÑдаÑи пеÑвой ÑÑÑоки и обÑÐ°Ñ ÑÑоимоÑÑÑ Ð²ÑдаÑи вÑеÑ
ÑÑÑок. ÐÐ»Ñ Ð±Ð¾Ð»ÑÑинÑÑва запÑоÑов важна обÑÐ°Ñ ÑÑоимоÑÑÑ, но в ÑакиÑ
конÑекÑÑаÑ
, как подзапÑÐ¾Ñ Ð² EXISTS, планиÑовÑик бÑÐ´ÐµÑ Ð¼Ð¸Ð½Ð¸Ð¼Ð¸Ð·Ð¸ÑоваÑÑ ÑÑоимоÑÑÑ Ð·Ð°Ð¿ÑÑка, а не обÑÑÑ ÑÑоимоÑÑÑ (Ñак как иÑполнение запÑоÑа вÑÑ Ñавно завеÑÑиÑÑÑ ÑÑÐ°Ð·Ñ Ð¿Ð¾Ñле полÑÑÐµÐ½Ð¸Ñ Ð¾Ð´Ð½Ð¾Ð¹ ÑÑÑоки). ÐÑоме Ñого, еÑли колиÑеÑÑво возвÑаÑаемÑÑ
ÑÑÑок огÑаниÑиваеÑÑÑ Ð¿Ñедложением LIMIT, планиÑовÑик инÑеÑполиÑÑÐµÑ ÑÑоимоÑÑÑ Ð¼ÐµÐ¶Ð´Ñ Ð´Ð²ÑÐ¼Ñ ÑÑими ÑиÑлами, вÑбиÑÐ°Ñ Ð½Ð°Ð¸Ð±Ð¾Ð»ÐµÐµ вÑгоднÑй план.
С паÑамеÑÑом ANALYZE опеÑаÑÐ¾Ñ Ð±ÑÐ´ÐµÑ Ð²Ñполнен на Ñамом деле, а не ÑолÑко запланиÑован. ÐÑи ÑÑом в вÑвод добавлÑÑÑÑÑ ÑакÑиÑеÑкие ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ вÑемени вÑполнениÑ, вклÑÑÐ°Ñ Ð¾Ð±Ñее вÑемÑ, заÑÑаÑенное на каждÑй Ñзел плана (в миллиÑекÑндаÑ
) и обÑее ÑиÑло ÑÑÑок, вÑданнÑÑ
в ÑезÑлÑÑаÑе. ÐÑо Ð¿Ð¾Ð¼Ð¾Ð³Ð°ÐµÑ Ð¿Ð¾Ð½ÑÑÑ, наÑколÑко близки к ÑеалÑноÑÑи пÑедваÑиÑелÑнÑе оÑенки планиÑовÑика.
Ðажно
ÐмейÑе в видÑ, ÑÑо Ñ Ñказанием ANALYZE опеÑаÑÐ¾Ñ Ð´ÐµÐ¹ÑÑвиÑелÑно вÑполнÑеÑÑÑ. ХоÑÑ EXPLAIN оÑбÑаÑÑÐ²Ð°ÐµÑ ÑезÑлÑÑаÑ, коÑоÑÑй веÑнÑл Ð±Ñ SELECT, в оÑÑалÑном вÑе дейÑÑÐ²Ð¸Ñ Ð²ÑполнÑÑÑÑÑ ÐºÐ°Ðº обÑÑно. ÐÑли Ð²Ñ Ñ
оÑиÑе вÑполниÑÑ EXPLAIN ANALYZE Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹ INSERT, UPDATE, DELETE, MERGE, CREATE TABLE AS или EXECUTE, не допÑÑÐºÐ°Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ
ÑÑой командой, воÑполÑзÑйÑеÑÑ Ñаким пÑиÑмом:
BEGIN; EXPLAIN ANALYZE ...; ROLLBACK;
Ðез Ñкобок Ð´Ð»Ñ ÑÑого опеÑаÑоÑа можно ÑказаÑÑ ÑолÑко паÑамеÑÑÑ ANALYZE и VERBOSE и ÑолÑко в Ñаком поÑÑдке. Ð PostgreSQL до веÑÑии 9.0 поддеÑживалÑÑ ÑолÑко ÑинÑакÑÐ¸Ñ Ð±ÐµÐ· Ñкобок, однако в далÑнейÑем ожидаеÑÑÑ, ÑÑо вÑе новÑе паÑамеÑÑÑ Ð±ÑдÑÑ Ð²Ð¾ÑпÑинимаÑÑÑÑ ÑолÑко в ÑкобкаÑ
.
ÐаÑамеÑÑÑ
ANALYZEÐÑполниÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð¸ вÑвеÑÑи ÑакÑиÑеÑкое вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¸ дÑÑгÑÑ ÑÑаÑиÑÑикÑ. Ðо ÑмолÑÐ°Ð½Ð¸Ñ ÑÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ Ñавен
FALSE.VERBOSEÐÑвеÑÑи дополниÑелÑнÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ плане запÑоÑа. Ð ÑаÑÑноÑÑи, вклÑÑиÑÑ ÑпиÑок ÑÑолбÑов ÑезÑлÑÑаÑа Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñзла в деÑеве плана, дополниÑÑ ÑÑ ÐµÐ¼Ð¾Ð¹ имена ÑÐ°Ð±Ð»Ð¸Ñ Ð¸ ÑÑнкÑий, вÑегда ÑказÑваÑÑ Ð´Ð»Ñ Ð¿ÐµÑеменнÑÑ Ð² вÑÑажениÑÑ Ð¿Ñевдоним Ð¸Ñ ÑаблиÑÑ, а Ñакже вÑводиÑÑ Ð¸Ð¼ÐµÐ½Ð° вÑÐµÑ ÑÑиггеÑов, Ð´Ð»Ñ ÐºÐ¾ÑоÑÑÑ Ð²ÑдаÑÑÑÑ ÑÑаÑиÑÑика. Также Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ запÑоÑа бÑÐ´ÐµÑ Ð²ÑводиÑÑÑÑ Ð¸Ð´ÐµÐ½ÑиÑикаÑоÑ, еÑли он бÑл вÑÑиÑлен; за подÑобноÑÑÑми обÑаÑиÑеÑÑ Ðº compute_query_id. Ðо ÑмолÑÐ°Ð½Ð¸Ñ ÑÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ Ñавен
FALSE.COSTSÐÑвеÑÑи ÑаÑÑÑиÑаннÑÑ ÑÑоимоÑÑÑ Ð·Ð°Ð¿ÑÑка и обÑÑÑ ÑÑоимоÑÑÑ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñзла плана, а Ñакже ÑаÑÑÑиÑанное ÑиÑло ÑÑÑок и ÑиÑÐ¸Ð½Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑÑÑоки. ÐÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ Ð¿Ð¾ ÑмолÑÐ°Ð½Ð¸Ñ Ñавен
TRUE.SETTINGSÐÑвеÑÑи инÑоÑмаÑÐ¸Ñ Ð¾ паÑамеÑÑÐ°Ñ ÐºÐ¾Ð½ÑигÑÑаÑии. Рименно, бÑдÑÑ Ð²ÑÐ²ÐµÐ´ÐµÐ½Ñ Ð¿Ð°ÑамеÑÑÑ, влиÑÑÑие на планиÑование, знаÑÐµÐ½Ð¸Ñ ÐºÐ¾ÑоÑÑÑ Ð¾ÑлиÑаÑÑÑÑ Ð¾Ñ ÑÑандаÑÑнÑÑ Ð·Ð½Ð°Ñений по ÑмолÑаниÑ. РоÑÑÑÑÑÑвие данного ÑÐºÐ°Ð·Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð´ÑазÑмеваеÑÑÑ
FALSE(ÑÑа инÑоÑмаÑÐ¸Ñ Ð½Ðµ вÑводиÑÑÑ).GENERIC_PLANÐÑполÑзоваÑÑ Ð¾Ð¿ÐµÑаÑоÑÑ Ñ Ñаблонами паÑамеÑÑов в виде
$1и ÑоздаÑÑ Ð¾Ð±Ñий план, не завиÑÑÑий Ð¾Ñ Ð·Ð½Ð°Ñений паÑамеÑÑов. Ðа подÑобной инÑоÑмаÑией об обÑÐ¸Ñ Ð¿Ð»Ð°Ð½Ð°Ñ Ð¸ ÑÐ¸Ð¿Ð°Ñ Ð¾Ð¿ÐµÑаÑоÑов, поддеÑживаÑÑÐ¸Ñ Ð¿Ð°ÑамеÑÑÑ, обÑаÑиÑеÑÑ ÐºPREPARE. ÐÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ Ð½ÐµÐ»ÑÐ·Ñ Ð¸ÑполÑзоваÑÑ ÑANALYZE. ÐнаÑение по ÑмолÑÐ°Ð½Ð¸Ñ âFALSE.BUFFERSÐклÑÑиÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾Ð± иÑполÑзовании бÑÑеÑа. Ð ÑаÑÑноÑÑи, вÑвеÑÑи ÑиÑло попаданий, блоков пÑоÑиÑаннÑÑ , загÑÑзнÑннÑÑ Ð¸ запиÑаннÑÑ Ð² ÑазделÑемом и локалÑном бÑÑеÑе, ÑиÑло пÑоÑиÑаннÑÑ Ð¸ запиÑаннÑÑ Ð²ÑеменнÑÑ Ð±Ð»Ð¾ÐºÐ¾Ð², а Ñакже вÑÐµÐ¼Ñ Ð² миллиÑекÑÐ½Ð´Ð°Ñ , поÑÑаÑенное на ÑÑение и запиÑÑ Ð±Ð»Ð¾ÐºÐ¾Ð² Ñайлов даннÑÑ Ð¸ блоков вÑеменнÑÑ Ñайлов, еÑли вклÑÑÑн паÑамеÑÑ track_io_timing. Ðопаданием (hit) ÑÑиÑаеÑÑÑ ÑиÑÑаÑиÑ, когда ÑÑебÑемÑй блок Ñже Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ Ð² кеÑе и ÑÑÐµÐ½Ð¸Ñ Ñ Ð´Ð¸Ñка ÑдаÑÑÑÑ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ. Ðлоки в обÑем бÑÑеÑе ÑодеÑÐ¶Ð°Ñ Ð´Ð°Ð½Ð½Ñе обÑÑнÑÑ ÑÐ°Ð±Ð»Ð¸Ñ Ð¸ индекÑов, в локалÑном â даннÑе вÑеменнÑÑ ÑÐ°Ð±Ð»Ð¸Ñ Ð¸ индекÑов, а вÑеменнÑе блоки пÑедназнаÑÐµÐ½Ñ Ð´Ð»Ñ ÐºÑаÑкоÑÑоÑного иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ñи вÑполнении ÑоÑÑиÑовки, Ñ ÐµÑиÑованиÑ, маÑеÑиализаÑии и подобнÑÑ Ñзлов плана. ЧиÑло загÑÑзнÑннÑÑ Ð±Ð»Ð¾ÐºÐ¾Ð² (dirtied) показÑваеÑ, ÑколÑко Ñанее не модиÑиÑиÑованнÑÑ Ð±Ð»Ð¾ÐºÐ¾Ð² изменила Ð´Ð°Ð½Ð½Ð°Ñ Ð¾Ð¿ÐµÑаÑиÑ; Ñогда как ÑиÑло запиÑаннÑÑ Ð±Ð»Ð¾ÐºÐ¾Ð² (written) показÑваеÑ, ÑколÑко Ñанее загÑÑзнÑннÑÑ Ð±Ð»Ð¾ÐºÐ¾Ð² даннÑй ÑеÑвеÑнÑй пÑоÑеÑÑ Ð²ÑÐ½ÐµÑ Ð¸Ð· кеÑа пÑи обÑабоÑке запÑоÑа. ÐнаÑениÑ, ÑказÑваемÑе Ð´Ð»Ñ Ñзла веÑÑ Ð½ÐµÐ³Ð¾ ÑÑовнÑ, вклÑÑаÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð²ÑÐµÑ ÐµÐ³Ð¾ доÑеÑÐ½Ð¸Ñ Ñзлов. Ð ÑекÑÑовом ÑоÑмаÑе вÑводÑÑÑÑ ÑолÑко ненÑлевÑе знаÑениÑ. ÐÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ Ð´ÐµÐ¹ÑÑвÑÐµÑ ÑолÑко в Ñежиме
ANALYZE. Ðо ÑмолÑÐ°Ð½Ð¸Ñ ÐµÐ³Ð¾ знаÑение ÑавноFALSE.WALÐклÑÑиÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ ÑоÑмиÑовании запиÑей WAL. Ð ÑаÑÑноÑÑи, вÑвеÑÑи ÑиÑло запиÑей, ÑиÑло полнÑÑ Ð¾Ð±Ñазов ÑÑÑÐ°Ð½Ð¸Ñ (fpi, full page images) и обÑÑм ÑгенеÑиÑованнÑÑ Ð·Ð°Ð¿Ð¸Ñей в байÑÐ°Ñ . Ð ÑекÑÑовом ÑоÑмаÑе вÑводÑÑÑÑ ÑолÑко ненÑлевÑе знаÑениÑ. ÐÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ, ÑолÑко еÑли Ñакже вклÑÑÑн Ñежим
ANALYZE. Ðо ÑмолÑÐ°Ð½Ð¸Ñ Ð¾Ð½ оÑклÑÑÑн (FALSE).TIMINGÐклÑÑиÑÑ Ð² вÑвод ÑакÑиÑеÑкое вÑÐµÐ¼Ñ Ð·Ð°Ð¿ÑÑка и вÑемÑ, заÑÑаÑенное на каждÑй Ñзел. ÐоÑÑоÑнное ÑÑение ÑиÑÑемнÑÑ ÑаÑов Ð¼Ð¾Ð¶ÐµÑ Ð·Ð½Ð°ÑиÑелÑно замедлиÑÑ Ð·Ð°Ð¿ÑоÑ, Ñак ÑÑо еÑли доÑÑаÑоÑно знаÑÑ ÑакÑиÑеÑкое ÑиÑло ÑÑÑок, Ð¸Ð¼ÐµÐµÑ ÑмÑÑл ÑделаÑÑ ÑÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ ÑавнÑм
FALSE. ÐÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð²Ñего опеÑаÑоÑа замеÑÑеÑÑÑ Ð²Ñегда, даже когда ÑÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ Ð²ÑклÑÑен и на ÑÑовне Ñзлов вÑÐµÐ¼Ñ Ð½Ðµ подÑÑиÑÑваеÑÑÑ. ÐÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ Ð´ÐµÐ¹ÑÑвÑÐµÑ ÑолÑко в ÑежимеANALYZE. Ðо ÑмолÑÐ°Ð½Ð¸Ñ ÐµÐ³Ð¾ знаÑение ÑавноTRUE.SUMMARYÐклÑÑиÑÑ ÑÐ²Ð¾Ð´ÐºÑ (напÑимеÑ, ÑÑммаÑное вÑемÑ) поÑле плана запÑоÑа. Сводка вклÑÑаеÑÑÑ Ð¿Ð¾ ÑмолÑаниÑ, когда иÑполÑзÑеÑÑÑ
ANALYZE, но ÑÑÐ¾Ñ Ð¿Ð°ÑамеÑÑ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÐµÑ Ð¿Ð¾Ð»ÑÑиÑÑ ÐµÑ Ð¸ Ñ Ð´ÑÑгими ваÑианÑами командÑ. ÐÑÐµÐ¼Ñ Ð¿Ð»Ð°Ð½Ð¸ÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð²EXPLAIN EXECUTEвклÑÑÐ°ÐµÑ Ð²ÑÐµÐ¼Ñ Ð¸Ð·Ð²Ð»ÐµÑÐµÐ½Ð¸Ñ Ð¿Ð»Ð°Ð½Ð° из кеÑа и вÑÐµÐ¼Ñ Ð¿ÐµÑепланиÑованиÑ, еÑли оно поÑÑебовалоÑÑ.FORMATУÑÑановиÑÑ Ð¾Ð´Ð¸Ð½ из ÑледÑÑÑÐ¸Ñ ÑоÑмаÑов вÑвода: TEXT, XML, JSON или YAML. ÐоÑледние ÑÑи ÑоÑмаÑа ÑодеÑÐ¶Ð°Ñ ÑÑ Ð¶Ðµ инÑоÑмаÑиÑ, ÑÑо и ÑекÑÑовÑй, но болÑÑе Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑ Ð´Ð»Ñ Ð¿ÑогÑаммного ÑазбоÑа. Ðо ÑмолÑÐ°Ð½Ð¸Ñ Ð²ÑбиÑаеÑÑÑ ÑоÑмаÑ
TEXT.booleanÐклÑÑÐ°ÐµÑ Ð¸Ð»Ð¸ оÑклÑÑÐ°ÐµÑ Ð·Ð°Ð´Ð°Ð½Ð½Ñй паÑамеÑÑ. ÐÐ»Ñ Ð²ÐºÐ»ÑÑÐµÐ½Ð¸Ñ Ð¿Ð°ÑамеÑÑа можно напиÑаÑÑ
TRUE,ONили1, а Ð´Ð»Ñ Ð¾ÑклÑÑÐµÐ½Ð¸Ñ âFALSE,OFFили0. ÐнаÑениеbooleanможно опÑÑÑиÑÑ, в ÑÑом ÑлÑÑае подÑазÑмеваеÑÑÑTRUE.опеÑаÑоÑÐÑбой опеÑаÑоÑ
SELECT,INSERT,UPDATE,DELETE,MERGE,VALUES,EXECUTE,DECLARE,CREATE TABLE ASиCREATE MATERIALIZED VIEW AS, план вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐºÐ¾ÑоÑого Ð²Ð°Ñ Ð¸Ð½ÑеÑеÑÑеÑ.
ÐÑÐ²Ð¾Ð´Ð¸Ð¼Ð°Ñ Ð¸Ð½ÑоÑмаÑиÑ
РезÑлÑÑаÑом ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð±ÑÐ´ÐµÑ ÑекÑÑовое опиÑание плана, вÑбÑанного Ð´Ð»Ñ Ð¾Ð¿ÐµÑаÑоÑа, возможно, дополненное ÑÑаÑиÑÑикой вÑполнениÑ. ÐÑедÑÑÐ°Ð²Ð»ÐµÐ½Ð½Ð°Ñ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾Ð¿Ð¸Ñана в Разделе 14.1.
ÐÑимеÑаниÑ
ЧÑÐ¾Ð±Ñ Ð¿Ð»Ð°Ð½Ð¸ÑовÑик запÑоÑов PostgreSQL бÑл доÑÑаÑоÑно инÑоÑмиÑован Ð´Ð»Ñ ÑÑÑекÑивной опÑимизаÑии запÑоÑов, даннÑе в pg_statistic Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð°ÐºÑÑалÑнÑми Ð´Ð»Ñ Ð²ÑеÑ
ÑаблиÑ, задейÑÑвованнÑÑ
в запÑоÑе. ÐбÑÑно об ÑÑом авÑомаÑиÑеÑки забоÑиÑÑÑ Ð´ÐµÐ¼Ð¾Ð½ авÑооÑиÑÑки. Ðо еÑли в ÑаблиÑе недавно пÑоизоÑли знаÑиÑелÑнÑе изменениÑ, Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑÑебоваÑÑÑÑ Ð²ÑÑÑнÑÑ Ð²ÑполниÑÑ ANALYZE, не дожидаÑÑÑ, пока авÑооÑиÑÑка обÑабоÑÐ°ÐµÑ ÑÑи изменениÑ.
ÐзмеÑÑÑ ÑакÑиÑеÑкÑÑ ÑÑоимоÑÑÑ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñзла в плане, ÑекÑÑÐ°Ñ ÑеализаÑÐ¸Ñ EXPLAIN ANALYZE пÑивноÑÐ¸Ñ Ð½Ð°ÐºÐ»Ð°Ð´Ð½Ñе ÑаÑÑ
Ð¾Ð´Ñ Ð¿ÑоÑилиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð² вÑполнение запÑоÑа. Ð ÑезÑлÑÑаÑе ÑÑого, пÑи запÑÑке запÑоÑа командой EXPLAIN ANALYZE он Ð¼Ð¾Ð¶ÐµÑ Ð²ÑполнÑÑÑÑÑ Ð·Ð½Ð°ÑиÑелÑно долÑÑе, Ñем пÑи обÑÑном вÑполнении. ÐбÑÑм накладнÑÑ
ÑаÑÑ
одов завиÑÐ¸Ñ Ð¾Ñ Ð¿ÑиÑÐ¾Ð´Ñ Ð·Ð°Ð¿ÑоÑа, а Ñакже Ð¾Ñ Ð¸ÑполÑзÑемой плаÑÑоÑмÑ. Ð¥ÑдÑÐ°Ñ ÑиÑÑаÑÐ¸Ñ Ð½Ð°Ð±Ð»ÑдаеÑÑÑ Ð´Ð»Ñ Ñзлов плана, коÑоÑÑе Ñами по Ñебе вÑполнÑÑÑÑÑ Ð¾ÑÐµÐ½Ñ Ð±ÑÑÑÑо, и в опеÑаÑионнÑÑ
ÑиÑÑемаÑ
, где полÑÑение ÑекÑÑего вÑемени оÑноÑиÑелÑно длиÑелÑÐ½Ð°Ñ Ð¾Ð¿ÐµÑаÑиÑ.
ÐÑимеÑÑ
ÐолÑÑение плана пÑоÑÑого запÑоÑа Ð´Ð»Ñ ÑаблиÑÑ, ÑодеÑжаÑей единÑÑвеннÑй ÑÑÐ¾Ð»Ð±ÐµÑ Ñипа integer, Ñ 10000 ÑÑÑок:
EXPLAIN SELECT * FROM foo;
QUERY PLAN
---------------------------------------------------------
Seq Scan on foo (cost=0.00..155.00 rows=10000 width=4)
(1 row)Ðлан Ñого же запÑоÑа, но вÑведеннÑй в ÑоÑмаÑе JSON:
EXPLAIN (FORMAT JSON) SELECT * FROM foo;
QUERY PLAN
--------------------------------
[ +
{ +
"Plan": { +
"Node Type": "Seq Scan",+
"Relation Name": "foo", +
"Alias": "foo", +
"Startup Cost": 0.00, +
"Total Cost": 155.00, +
"Plan Rows": 10000, +
"Plan Width": 4 +
} +
} +
]
(1 row)ÐÑли в ÑаблиÑе еÑÑÑ Ð¸Ð½Ð´ÐµÐºÑ, а в запÑоÑе пÑиÑÑÑÑÑвÑÐµÑ ÑÑловие WHERE, Ð´Ð»Ñ ÐºÐ¾ÑоÑого полезен ÑÑÐ¾Ñ Ð¸Ð½Ð´ÐµÐºÑ, EXPLAIN Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÐºÐ°Ð·Ð°ÑÑ Ð´ÑÑгой план:
EXPLAIN SELECT * FROM foo WHERE i = 4;
QUERY PLAN
--------------------------------------------------------------
Index Scan using fi on foo (cost=0.00..5.98 rows=1 width=4)
Index Cond: (i = 4)
(2 rows)Ðлан Ñого же запÑоÑа, но в ÑоÑмаÑе YAML:
EXPLAIN (FORMAT YAML) SELECT * FROM foo WHERE i='4';
QUERY PLAN
-------------------------------
- Plan: +
Node Type: "Index Scan" +
Scan Direction: "Forward"+
Index Name: "fi" +
Relation Name: "foo" +
Alias: "foo" +
Startup Cost: 0.00 +
Total Cost: 5.98 +
Plan Rows: 1 +
Plan Width: 4 +
Index Cond: "(i = 4)"
(1 row)РаÑÑмоÑÑение ÑоÑмаÑа XML оÑÑавлено в каÑеÑÑве ÑпÑÐ°Ð¶Ð½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÑиÑаÑелÑ.
Ðлан Ñого же запÑоÑа без вÑвода оÑенок ÑÑоимоÑÑи:
EXPLAIN (COSTS FALSE) SELECT * FROM foo WHERE i = 4;
QUERY PLAN
----------------------------
Index Scan using fi on foo
Index Cond: (i = 4)
(2 rows)ÐÑÐ¸Ð¼ÐµÑ Ð¿Ð»Ð°Ð½Ð° Ð´Ð»Ñ Ð·Ð°Ð¿ÑоÑа Ñ Ð°Ð³ÑегаÑной ÑÑнкÑией:
EXPLAIN SELECT sum(i) FROM foo WHERE i < 10;
QUERY PLAN
-------------------------------------------------------------------â--
Aggregate (cost=23.93..23.93 rows=1 width=4)
-> Index Scan using fi on foo (cost=0.00..23.92 rows=6 width=4)
Index Cond: (i < 10)
(3 rows)ÐÑÐ¸Ð¼ÐµÑ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ EXPLAIN EXECUTE Ð´Ð»Ñ Ð¾ÑобÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð»Ð°Ð½Ð° вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ð³Ð¾Ñовленного запÑоÑа:
PREPARE query(int, int) AS SELECT sum(bar) FROM test
WHERE id > $1 AND id < $2
GROUP BY foo;
EXPLAIN ANALYZE EXECUTE query(100, 200);
QUERY PLAN
-------------------------------------------------------------------â------------------------------------------------------
HashAggregate (cost=10.77..10.87 rows=10 width=12) (actual time=0.043..0.044 rows=10 loops=1)
Group Key: foo
Batches: 1 Memory Usage: 24kB
-> Index Scan using test_pkey on test (cost=0.29..10.27 rows=99 width=8) (actual time=0.009..0.025 rows=99 loops=1)
Index Cond: ((id > 100) AND (id < 200))
Planning Time: 0.244 ms
Execution Time: 0.073 ms
(7 rows)РазÑмееÑÑÑ, конкÑеÑнÑе ÑиÑла, показаннÑе здеÑÑ, завиÑÑÑ Ð¾Ñ ÑакÑиÑеÑкого ÑодеÑжимого задейÑÑвованнÑÑ
ÑаблиÑ. Также ÑÑÑиÑе, ÑÑо ÑÑи ÑиÑла и даже вÑбÑÐ°Ð½Ð½Ð°Ñ ÑÑÑаÑÐµÐ³Ð¸Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа могÑÑ Ð¼ÐµÐ½ÑÑÑÑÑ Ð¾Ñ Ð²ÐµÑÑии к веÑÑии PostgreSQL вÑледÑÑвие ÑÑовеÑÑенÑÑÐ²Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð»Ð°Ð½Ð¸ÑовÑика. ÐÑоме Ñого, команда ANALYZE пÑи обÑабоÑке ÑÑаÑиÑÑиÑеÑкиÑ
даннÑÑ
пÑÐ¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ ÑлÑÑайнÑе вÑбоÑки, Ñак ÑÑо оÑенки ÑÑоимоÑÑи могÑÑ Ð¼ÐµÐ½ÑÑÑÑÑ Ð¿Ñи каждом ÑиÑÑом запÑÑке ANALYZE, даже когда ÑакÑиÑеÑкое ÑаÑпÑеделение даннÑÑ
в ÑаблиÑе не менÑеÑÑÑ.
ÐбÑаÑиÑе внимание, ÑÑо в пÑедÑдÑÑем пÑимеÑе показан «ÑпеÑиализиÑованнÑй» план Ð´Ð»Ñ Ð·Ð°Ð¿ÑоÑа EXECUTE Ñ Ð¾Ð¿ÑеделÑннÑми знаÑениÑми паÑамеÑÑов. С помоÑÑÑ GENERIC_PLAN можно Ñакже поÑмоÑÑеÑÑ Ð¾Ð±Ñий план Ð´Ð»Ñ Ð¿Ð°ÑамеÑÑизованного запÑоÑа:
EXPLAIN (GENERIC_PLAN)
SELECT sum(bar) FROM test
WHERE id > $1 AND id < $2
GROUP BY foo;
QUERY PLAN
-------------------------------------------------------------------â------------
HashAggregate (cost=26.79..26.89 rows=10 width=12)
Group Key: foo
-> Index Scan using test_pkey on test (cost=0.29..24.29 rows=500 width=8)
Index Cond: ((id > $1) AND (id < $2))
(4 rows) Ð ÑÑом ÑлÑÑае анализаÑÐ¾Ñ Ð·Ð°Ð¿ÑоÑа коÑÑекÑно пÑедполагаеÑ, ÑÑо $1 и $2 Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¸Ð¼ÐµÑÑ ÑÐ¾Ñ Ð¶Ðµ Ñип даннÑÑ
, ÑÑо и id, Ñак ÑÑо оÑÑÑÑÑÑвие инÑоÑмаÑии о Ñипе даннÑÑ
из PREPARE не пÑедÑÑавлÑÐµÑ Ð¿ÑоблемÑ. РдÑÑгиÑ
ÑлÑÑаÑÑ
Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑÑебоваÑÑÑÑ Ñвно ÑказаÑÑ ÑÐ¸Ð¿Ñ Ð´Ð»Ñ Ñимволов паÑамеÑÑов, ÑÑо можно ÑделаÑÑ Ð¿ÑÑÑм пÑÐ¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ñипов, напÑимеÑ:
EXPLAIN (GENERIC_PLAN)
SELECT sum(bar) FROM test
WHERE id > $1::integer AND id < $2::integer
GROUP BY foo;СовмеÑÑимоÑÑÑ
ÐпеÑаÑÐ¾Ñ EXPLAIN оÑÑÑÑÑÑвÑÐµÑ Ð² ÑÑандаÑÑе SQL.