38.11. ÐнÑоÑмаÑÐ¸Ñ Ð´Ð»Ñ Ð¾Ð¿ÑимизаÑии ÑÑнкÑий
Сама по Ñебе ÑÑнкÑÐ¸Ñ Ð´Ð»Ñ Ð¡Ð£ÐÐ ÑвлÑеÑÑÑ Ð¿ÑоÑÑо «ÑÑÑнÑм ÑÑиком», о поведении коÑоÑого извеÑÑно оÑÐµÐ½Ñ Ð¼Ð°Ð»Ð¾. ÐÑо ознаÑаеÑ, ÑÑо запÑоÑÑ, вÑзÑваÑÑие ÑÑнкÑии, могÑÑ Ð²ÑполнÑÑÑÑÑ Ð³Ð¾Ñаздо менее ÑÑÑекÑивно, Ñем могли Ð±Ñ Ð² ÑеоÑии. ÐоÑÑÐ¾Ð¼Ñ Ð¸Ð¼ÐµÐµÑÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ ÑообÑиÑÑ Ð¿Ð»Ð°Ð½Ð¸ÑовÑÐ¸ÐºÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ ÑÑнкÑии, коÑоÑÑе помогÑÑ ÐµÐ¼Ñ Ð¾Ð¿ÑимизиÑоваÑÑ Ð²ÑÐ·Ð¾Ð²Ñ ÑÑнкÑий.
ÐекоÑоÑÑе оÑновнÑе ÑакÑÑ Ð¿ÐµÑедаÑÑÑÑ Ð´ÐµÐºÐ»Ð°ÑаÑивнÑм обÑазом в команде CREATE FUNCTION; в иÑ
ÑиÑле один из ÑамÑÑ
знаÑимÑÑ
â Ñ
аÑакÑеÑиÑÑика изменÑивоÑÑи (IMMUTABLE, STABLE или VOLATILE). Ð¡Ð¾Ð·Ð´Ð°Ð²Ð°Ñ Ð»ÑбÑÑ ÑÑнкÑиÑ, оÑÐµÐ½Ñ Ð²Ð°Ð¶Ð½Ð¾ пÑавилÑно опÑеделиÑÑ ÑÑÑ Ñ
аÑакÑеÑиÑÑикÑ. Также Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð¿ÑеделÑÑÑÑÑ Ñ
аÑакÑеÑиÑÑика ÑаÑпаÑÐ°Ð»Ð»ÐµÐ»Ð¸Ð²Ð°Ð½Ð¸Ñ (PARALLEL UNSAFE, PARALLEL RESTRICTED или PARALLEL SAFE), еÑли Ð²Ñ ÑаÑÑÑиÑÑваеÑе, ÑÑо ÑÑа ÑÑнкÑÐ¸Ñ Ð±ÑÐ´ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ Ð² ÑаÑпаÑаллеливаемÑÑ
запÑоÑаÑ
. ÐÑоме Ñого, Ð´Ð»Ñ ÑÑнкÑии Ð¼Ð¾Ð¶ÐµÑ Ð·Ð°Ð´Ð°Ð²Ð°ÑÑÑÑ Ð¿ÑимеÑÐ½Ð°Ñ ÑÑоимоÑÑÑ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¸/или оÑенка колиÑеÑÑва ÑÑÑок, вÑдаваемого ÑÑнкÑией, возвÑаÑаÑÑей множеÑÑво. Ðднако деклаÑаÑивнÑй ÑпоÑоб опиÑÐ°Ð½Ð¸Ñ Ð´Ð²ÑÑ
поÑледниÑ
ÑакÑов позволÑÐµÑ Ð·Ð°Ð´Ð°ÑÑ ÑолÑко некоÑоÑое поÑÑоÑнное знаÑение, а ÑÑо полезно далеко не вÑегда.
Ðо имееÑÑÑ Ñакже возможноÑÑÑ ÑвÑзаÑÑ Ð²ÑпомогаÑелÑнÑÑ ÑÑнкÑÐ¸Ñ Ð´Ð»Ñ Ð¿Ð»Ð°Ð½Ð¸ÑовÑика Ñ Ð²ÑзÑваемой из SQL ÑÑнкÑией (она бÑÐ´ÐµÑ Ñелевой ÑÑнкÑией Ð´Ð»Ñ Ð¿ÐµÑвой), и пеÑедаÑÑ ÑеÑез Ð½ÐµÑ ÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ Ñелевой ÑÑнкÑии, коÑоÑÐ°Ñ ÑлиÑком Ñложна Ð´Ð»Ñ Ð¿ÑедÑÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð² деклаÑаÑивном виде. ÐÑпомогаÑелÑнÑе ÑÑнкÑии Ð´Ð»Ñ Ð¿Ð»Ð°Ð½Ð¸ÑовÑика должнÑм бÑÑÑ Ð½Ð°Ð¿Ð¸ÑÐ°Ð½Ñ Ð½Ð° C (Ñ Ð¾ÑÑ ÑзÑк ÑелевÑÑ ÑÑнкÑий Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð»ÑбÑм), ÑÑо пеÑÐµÐ²Ð¾Ð´Ð¸Ñ Ð¸Ñ Ð² каÑегоÑÐ¸Ñ ÑаÑÑиÑеннÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑей, и ÑазÑабаÑÑваÑÑ Ð¸Ñ Ð±ÑдÑÑ Ð¾ÑноÑиÑелÑно немногие полÑзоваÑели.
ÐÑпомогаÑелÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° имеÑÑ Ð² SQL ÑакÑÑ ÑигнаÑÑÑÑ:
supportfn(internal) returns internal
Ðна ÑвÑзÑваеÑÑÑ Ñ Ñелевой ÑÑнкÑией Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÑÐºÐ°Ð·Ð°Ð½Ð¸Ñ SUPPORT в команде, ÑоздаÑÑей ÑелевÑÑ ÑÑнкÑиÑ.
ÐодÑобное опиÑание API можно найÑи в Ñайле src/include/nodes/supportnodes.h в иÑÑ
одном коде PostgreSQL. ÐдеÑÑ Ð´Ð°ÑÑÑÑ ÑолÑко обÑее пÑедÑÑавление о Ñом, ÑÑо могÑÑ Ð´ÐµÐ»Ð°ÑÑ Ð²ÑпомогаÑелÑнÑе ÑÑнкÑии Ð´Ð»Ñ Ð¿Ð»Ð°Ð½Ð¸ÑовÑика. ÐножеÑÑво запÑоÑов к вÑпомогаÑелÑнÑм ÑÑнкÑиÑм ÑаÑÑиÑÑемое, Ñак ÑÑо в бÑдÑÑиÑ
веÑÑиÑÑ
Ñ Ð½Ð¸Ñ
могÑÑ Ð¿Ð¾ÑвиÑÑÑÑ Ð¸ дÑÑгие возможноÑÑи.
ÐекоÑоÑÑе вÑÐ·Ð¾Ð²Ñ ÑÑнкÑий можно ÑпÑоÑÑиÑÑ Ð²Ð¾ вÑÐµÐ¼Ñ Ð¿Ð»Ð°Ð½Ð¸ÑованиÑ, в завиÑимоÑÑи Ð¾Ñ Ð¾ÑобенноÑÑей ÑÑнкÑии. ÐапÑимеÑ, вÑзов int4mul(n, 1) можно ÑвеÑÑи пÑоÑÑо к n. ÐÑеобÑазование Ñакого Ñода Ð¼Ð¾Ð¶ÐµÑ Ð²ÑполнÑÑÑÑÑ Ð²ÑпомогаÑелÑной ÑÑнкÑией, еÑли она обÑабаÑÑÐ²Ð°ÐµÑ Ð·Ð°Ð¿ÑоÑÑ Ñипа SupportRequestSimplify. ÐÑа вÑпомогаÑелÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð±ÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ ÑкземплÑÑа вÑзова Ñелевой ÑÑнкÑии, найденного в деÑеве ÑазобÑанного запÑоÑа. ÐÑли она обнаÑÑживаеÑ, ÑÑо ÑÑÐ¾Ñ ÐºÐ¾Ð½ÐºÑеÑнÑй вÑзов можно ÑпÑоÑÑиÑÑ Ð¸ пÑивеÑÑи к дÑÑÐ³Ð¾Ð¼Ñ Ð²Ð¸Ð´Ñ, она Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑÑÑоиÑÑ Ð¸ возвÑаÑиÑÑ Ð´ÑÑгое деÑево Ñ Ð¸Ð·Ð¼ÐµÐ½ÑннÑм вÑÑажением. ÐÑо бÑÐ´ÐµÑ Ð°Ð²ÑомаÑиÑеÑки ÑабоÑаÑÑ Ð¸ Ð´Ð»Ñ Ð¾Ð¿ÐµÑаÑоÑов, оÑнованнÑÑ
на ÑÑнкÑиÑÑ
, â в данном пÑимеÑе n * 1 бÑÐ´ÐµÑ Ñакже ÑпÑоÑено до n. (Ðо замеÑÑÑе, ÑÑо ÑÑо пÑоÑÑо иллÑÑÑÑаÑиÑ; конкÑеÑно ÑÑÑ Ð¾Ð¿ÑимизаÑÐ¸Ñ ÑÑандаÑÑнÑй PostgreSQL не пÑоизводиÑ). ÐÑи ÑÑом не гаÑанÑиÑÑеÑÑÑ, ÑÑо PostgreSQL никогда не вÑÐ·Ð¾Ð²ÐµÑ ÑелевÑÑ ÑÑнкÑÐ¸Ñ Ð² ÑлÑÑаÑÑ
, коÑоÑÑе Ð¼Ð¾Ð¶ÐµÑ ÑпÑоÑÑиÑÑ Ð²ÑпомогаÑелÑÐ½Ð°Ñ ÑÑнкÑиÑ. С ÑÑÑÑом ÑÑого важно обеÑпеÑиÑÑ ÑÑÑогÑÑ Ð¸Ð´ÐµÐ½ÑиÑноÑÑÑ ÑпÑоÑÑнного вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ ÑакÑиÑеÑÐºÐ¾Ð¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñелевой ÑÑнкÑии.
ÐÐ»Ñ Ñелевой ÑÑнкÑии, возвÑаÑаÑÑей знаÑение boolean, ÑаÑÑо бÑÐ²Ð°ÐµÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð¾ оÑениÑÑ, какой пÑоÑÐµÐ½Ñ ÑÑÑок бÑÐ´ÐµÑ Ð²ÑбÑан пÑедложением WHERE, в коÑоÑом вÑзÑваеÑÑÑ ÑÑа ÑÑнкÑиÑ. ÐÑÑ Ð¾ÑÐµÐ½ÐºÑ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÐµÑ Ð¿Ð¾Ð»ÑÑиÑÑ Ð²ÑпомогаÑелÑÐ½Ð°Ñ ÑÑнкÑиÑ, обÑабаÑÑваÑÑÐ°Ñ Ð·Ð°Ð¿ÑоÑÑ Ñипа SupportRequestSelectivity.
ÐÑли алгоÑиÑм ÑабоÑÑ Ñелевой ÑÑнкÑии знаÑиÑелÑно менÑеÑÑÑ Ð² завиÑимоÑÑи Ð¾Ñ ÐµÑ Ð°ÑгÑменÑов, Ð´Ð»Ñ Ð½ÐµÑ Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ ÑмÑÑл вÑÑиÑлÑÑÑ Ð¿ÐµÑеменнÑÑ Ð¾ÑÐµÐ½ÐºÑ ÑÑоимоÑÑи. ÐÑо можно ÑделаÑÑ, Ñеализовав вÑпомогаÑелÑнÑÑ ÑÑнкÑиÑ, коÑоÑÐ°Ñ Ð±ÑÐ´ÐµÑ Ð¾Ð±ÑабаÑÑваÑÑ Ð·Ð°Ð¿ÑоÑÑ Ñипа SupportRequestCost.
ÐÐ»Ñ Ñелевой ÑÑнкÑии, возвÑаÑаÑÑей множеÑÑво, ÑаÑÑо полезно имеÑÑ Ð¿ÐµÑеменнÑÑ Ð¾ÑÐµÐ½ÐºÑ ÑиÑла вÑдаваемÑÑ
ÑÑÑок. РеализоваÑÑ ÑÑо позволÑÐµÑ Ð²ÑпомогаÑелÑÐ½Ð°Ñ ÑÑнкÑиÑ, обÑабаÑÑваÑÑÐ°Ñ Ð·Ð°Ð¿ÑоÑÑ Ñипа SupportRequestRows.
ÐÐ»Ñ Ñелевой ÑÑнкÑии, возвÑаÑаÑÑей знаÑение boolean, Ð¼Ð¾Ð¶ÐµÑ ÑÑÑеÑÑвоваÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑÑ Ð¿ÑеобÑазоваÑÑ Ð²Ñзов ÑÑнкÑии в ÑÑловии WHERE в пÑедложение(Ñ) Ñ Ð¸Ð½Ð´ÐµÐºÑиÑÑемÑми опеÑаÑоÑами. ÐÑеобÑазованнÑе пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð² ÑоÑноÑÑи иденÑиÑÐ½Ñ ÑÑÐ»Ð¾Ð²Ð¸Ñ ÑÑнкÑии либо могÑÑ Ð±ÑÑÑ Ð½ÐµÑколÑко менее ÑÑÑогими (Ñо еÑÑÑ Ð¾Ð½Ð¸ могÑÑ Ð¿ÑинимаÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе знаÑениÑ, не ÑдовлеÑвоÑÑÑÑие ÑÑÐ»Ð¾Ð²Ð¸Ñ Ñ ÑÑнкÑией). РпоÑледнем ÑлÑÑае ÑÑловие Ñ Ð¸Ð½Ð´ÐµÐºÑом ÑÑиÑаеÑÑÑ Ð½ÐµÑоÑнÑм; оно Ð¼Ð¾Ð¶ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка по индекÑÑ, но Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑÑÑоки, полÑÑенной пÑи Ñаком поиÑке, должна вÑзÑваÑÑÑÑ ÑÑнкÑиÑ, ÑÑÐ¾Ð±Ñ ÑоÑно опÑеделиÑÑ, ÑдовлеÑвоÑÑÐµÑ Ð»Ð¸ ÑÑÑока ÑÑÐ»Ð¾Ð²Ð¸Ñ WHERE. ÐÐ»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑакиÑ
ÑÑловий вÑпомогаÑелÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° обÑабаÑÑваÑÑ Ð·Ð°Ð¿ÑоÑÑ Ñипа SupportRequestIndexCondition.