На практика те ще бъдат изпълнени в дадения ред, но няма гаранция.
Ако е гарантирано, тогава ще бъде покрито в документацията или стандарта SQL. Не виждам никакво споменаване на реда на изпълнение на UNION
в двете.
Ако оптимизаторът имаше причина да изпълни единия преди другия, щеше да е свободен да го направи.
За да осигурите ред на изпълнение, изпълнете изрази в желания ред:
SELECT * FROM func1();
SELECT * FROM func2();
Ако искате да намалите двупосочните пътувания, използвайте съоръженията за пакетиране на клиента, ако е възможно, или използвайте DO
блокиране:
DO
$$
BEGIN
PERFORM proc1();
PERFORM proc2();
END;
$$;
Ако трябва да върнете стойности, използвайте функция и RETURN QUERY
или RETURN NEXT
.
Или можете да наложите поръчка с CTE, защото в PostgreSQL (за съжаление) CTE действат като оптимизационни прегради, които принуждават материализирането на резултатите . Въпреки това, AFAIK PostgreSQL все още не трябва да изпълнява условията на CTE в реда, в който са написани или в реда, в който са посочени; единствената гаранция, която получавате, е ако направите това:
WITH f1 AS (SELECT * FROM function1())
SELECT * FROM function2()
UNION ALL
SELECT * FROM f1;
след това function1
първо трябва да се изпълни и материализира. Това обаче е специфична за PostgreSQL грешка; това не е вярно за други машини за бази данни, не е гарантирано от стандарта и не трябва да разчитате на него.
Това не се отнася до
WITH f1 AS (SELECT * FROM function1())
f2 AS (SELECT * FROM function2())
SELECT * FROM f2
UNION ALL
SELECT * FROM f1;
... тъй като в този случай PostgreSQL може да изпълни независимите условия на CTE в двата реда.
Отново, с обединенията се прилага същият принцип. Ако термините са независими, тогава системата може да избере да ги изпълнява в произволен ред, въпреки че обикновено не го прави. И така:
select null::void from (select 1 from foo() ) left join (select 1 from bar()) on true
може да оцени и материализира bar()
след това обединете резултатите му на foo()
.
Ако искате подредено изпълнение, не трябва да разчитате на наборни операции като обединения и присъединявания. Използвайте отделни заявки или процедурен код.
Да, има.
SELECT * FROM function1();
SELECT * FROM function2();