Мушкилот бо ситорача: CTE-ҳоро лона кардан мумкин аст.
Хеле суст лона гузошта шудаанд ва ҳатто як ном доранд. Масалан, шумо метавонед дар дохили CTE A кунад CTE X, ва дар як сатҳ дар дохили CTE B боз кунед CTE X:
WITH A AS (
WITH X AS (...)
SELECT ...
)
, B AS (
WITH X AS (...)
SELECT ...
)
...
Агар мо дар дархост калимаи калидӣ дошта бошем UNION [ALL] (оператори пайвастани ду намуна), пас дар нақша он ба ё гиреҳ мувофиқат мекунад Append, ё баъзе Recursive Union.
Он чизе ки дар боло "боло" аст UNION - ин аввалин авлоди гиреҳи мост, ки "поён" аст - дуюм. Агар гузашт UNION мо якчанд блокро якбора «часпонда» дорем, пас Append-ҳанӯз танҳо як гиреҳ хоҳад буд, аммо он ду не, балки бисёр фарзанд хоҳад дошт - мувофиқи тартиби онҳо:
(...) -- #1
UNION ALL
(...) -- #2
UNION ALL
(...) -- #3
Append
-> ... #1
-> ... #2
-> ... #3
Мушкилот бо ситорача: дар дохили тавлиди намунаи рекурсивӣ (WITH RECURSIVE) инчунин метавонад зиёда аз як бошад UNION. Аммо танҳо блоки охирин пас аз охирин ҳамеша рекурсивӣ аст UNION. Ҳама чиз дар боло як аст, аммо гуногун UNION:
WITH RECURSIVE T AS(
(...) -- #1
UNION ALL
(...) -- #2, тут кончается генерация стартового состояния рекурсии
UNION ALL
(...) -- #3, только этот блок рекурсивный и может содержать обращение к T
)
...
Шумо инчунин бояд ин гуна мисолҳоро «часпида» тавонед. Дар ин мисол мо мебинем UNION-Дар дархости мо 3 бахш буд. Мувофики он, як UNION мувофиқат мекунад Append- гиреҳ ва ба дигар - Recursive Union.
Хондан-навиштан маълумот
Ҳама чиз тартиб дода шудааст, ҳоло мо медонем, ки кадом қисми дархост ба кадом қисми нақша мувофиқ аст. Ва дар ин порчаҳо мо метавонем ба осонӣ ва табиатан он ашёҳоеро пайдо кунем, ки "хондан" ҳастанд.
Аз нуқтаи назари пурсиш, мо намедонем, ки ин ҷадвал аст ё CTE, аммо онҳо аз ҷониби як гиреҳ таъин карда мешаванд RangeVar. Ва аз нуқтаи назари "хондан" ин инчунин маҷмӯи хеле маҳдуди гиреҳҳост:
Seq Scan on [tbl]
Bitmap Heap Scan on [tbl]
Index [Only] Scan [Backward] using [idx] on [tbl]
CTE Scan on [cte]
Insert/Update/Delete on [tbl]
Мо сохтори план ва дархостро медонем, мукотибаи блокхоро медонем, номи объектхоро медонем - як ба як мукоиса мекунем.
Боз вазифаи "бо ситорача". Мо дархостро қабул мекунем, иҷро мекунем, мо ягон тахаллус надорем - мо онро танҳо ду маротиба аз ҳамон CTE мехонем.
Мо ба накша назар меандозем — мушкилй дар чист? Чаро мо тахаллус доштем? Мо онро фармоиш надодаем. Чунин «рақами рақам»-ро аз куҷо пайдо мекунад?
PostgreSQL онро худаш илова мекунад. Шумо танҳо бояд инро фаҳмед маҳз ҳамин гуна тахаллус барои мо бо максади мукоиса бо план ягон маъно надорад, дар ин чо факат илова карда мешавад. Биёед ба ӯ аҳамият надиҳем.
Дуюм вазифаи "бо ситорача": агар мо аз ҷадвали тақсимшуда хонем, он гоҳ гиреҳ мегирем Append ё Merge Append, ки аз шумораи зиёди «бачагон» иборат хоханд буд ва хар кадоми онхо ба навъе хоханд буд Scan'om аз бахши ҷадвал: Seq Scan, Bitmap Heap Scan ё Index Scan. Аммо, дар ҳар сурат, ин "кӯдакон" дархостҳои мураккаб нахоҳанд буд - ҳамин тавр ин гиреҳҳоро аз онҳо фарқ кардан мумкин аст. Append Дар бораи мо UNION.
Мо низ чунин гиреххоро мефахмем, онхоро «як туда» чамъ мекунем ва мегуем: «ҳар чизе ки шумо аз megatable мехонед, дар ин ҷо ва поёни дарахт аст".
Гиреҳҳои қабули маълумотҳои "оддӣ"
Values Scan ба план мувофик аст VALUES дар дархост.
Result дархост бе он аст FROM Мисли SELECT 1. Ё вақте ки шумо изҳори дидаву дониста бардурӯғ доред WHERE-блок (пас атрибут пайдо мешавад One-Time Filter):
EXPLAIN ANALYZE
SELECT * FROM pg_class WHERE FALSE; -- или 0 = 1
Аммо бо дархостҳои лона ҳама чиз мураккабтар аст - мутаассифона, онҳо на ҳамеша ба онҳо табдил меёбанд InitPlan/SubPlan. Баъзан ба онҳо табдил меёбанд ... Join ё ... Anti Join, махсусан вақте ки шумо чизе монанди нависед WHERE NOT EXISTS .... Ва дар ин чо на хама вакт онхоро якчоя кардан мумкин аст — дар матни план ягон оператори ба узелхои план мувофик нест.
Боз вазифаи "бо ситорача": баъзе VALUES дар дархост. Дар ин ҳолат ва дар нақша шумо якчанд гиреҳ мегиред Values Scan.
Суффиксҳои "рақамдор" барои фарқ кардани онҳо аз якдигар кӯмак мекунанд - онҳо маҳз бо тартиби пайдо шудани суффиксҳои мувофиқ илова карда мешаванд. VALUES-дар баробари дархост аз боло то поён блок мекунад.
Биёед қайд кунем, ки мо гиреҳҳое дорем, ки ҳамзамон фарзандони B ва C доранд - ба мо аҳамият намедиҳад, ки бо кадом тартиб. Биёед онҳоро якҷоя кунем ва тасвири гиреҳро гардонем.
Биёед бори дигар назар кунем. Ҳоло мо гиреҳҳо бо кӯдакони А ва ҷуфтҳо (B + C) дорем - бо онҳо низ мувофиқанд.
Аҷоиб! Маълум мешавад, ки мо ин ду ҳастем JOIN аз су-пориш бо плану узелхо бомуваффакият якчоя карда шуданд.
Афсус, ки ин масъала на хамеша хал мешавад.
Масалан, агар дар дархост A JOIN B JOIN C, ва дар план бошад, пеш аз хама гиреххои «берунй»-и А ва С васл карда шуданд.. Аммо дар дархост чунин оператор нест, мо чизе барои таъкид кардан, чизе барои ишора кардан надорем. Ҳангоми навиштан бо "вергул" ҳамин аст A, B.
Аммо, дар аксари ҳолатҳо, қариб ҳамаи гиреҳҳоро метавон "кушода" кард ва шумо метавонед ин намуди профилро дар тарафи чап сари вақт ба даст оред - айнан, ба монанди Google Chrome ҳангоми таҳлили коди JavaScript. Шумо мебинед, ки ҳар як сатр ва ҳар як изҳорот барои "иҷро кардан" чӣ қадар вақт лозим буд.
Ва барои он ки барои шумо истифода бурдани ин ҳама қулайтар шавад, мо анборро сохтем бойгонӣ, ки дар он шумо метавонед нақшаҳои худро захира кунед ва дертар дар якҷоягӣ бо дархостҳои алоқаманд пайдо кунед ё истинодро бо касе мубодила кунед.