Большое количество циклов в плане запроса
Запросы к базе стали выполняться значительно медленней.
Стал смотреть план запроса, обратил внимание на большое количество циклов.
Подскажите, в чем может быть причина, большого количества loops в плане запроса?
Nested Loop Left Join (cost=2.80..17.66 rows=1 width=245) (actual time=373.387..113483.812 rows=1 loops=1)
-> Nested Loop Left Join (cost=2.52..15.15 rows=1 width=184) (actual time=373.379..113483.804 rows=1 loops=1)
Join Filter: (t1._idrref = t5._fld21037rref)
-> Nested Loop Left Join (cost=1.95..10.08 rows=1 width=135) (actual time=373.369..113483.794 rows=1 loops=1)
Join Filter: (t1._fld5345rref = t6._idrref)
Rows Removed by Join Filter: 706
-> Index Scan using _reference279hpk on _reference279 t1 (cost=0.29..1.89 rows=1 width=40) (actual time=0.017..0.023 rows=1 loops=1)
Index Cond: ((_fld1077 = 137::numeric) AND (_idrref = ‘\\x80c3f9aa551a7ef811e7be6e3605cc45’::bytea))
-> Nested Loop Left Join (cost=1.
Join Filter: ((t6._fld2543_type = CASE WHEN (t7._idrref IS NOT NULL) THEN ‘\\x08’::bytea ELSE NULL::bytea END) AND (t6._fld2543_rtref = CASE WHEN (t7._idrref IS NOT NULL) THEN ‘\\x0000014d’::bytea ELSE NULL::bytea END) AND (t6._fld2543_rrref = t7._idrref))
Rows Removed by Join Filter: 357238
-> Index Scan using _reference125hpk on _reference125 t6 (cost=0.42..2.03 rows=1 width=53) (actual time=0.031..1.150 rows=707 loops=1)
Index Cond: (_fld1077 = 137::numeric)
-> Nested Loop Left Join (cost=1.25..6.14 rows=1 width=135) (actual time=0.316..160.267 rows=506 loops=707)
Join Filter: (t7._idrref = t11._fld24519rref)
Rows Removed by Join Filter: 505
-> Index Scan using _reference333hpk on _reference333 t7 (cost=0.42..2.02 rows=1 width=70) (actual time=0.009..0.303 rows=506 loops=707)
Index Cond: (_fld1077 = 137::numeric)
-> Nested Loop (cost=0.83. .4.10 rows=1 width=65) (actual time=0.101..0.315 rows=1 loops=357742)
Join Filter: ((t10._fld24519rref = t11._fld24519rref) AND ((max(t10._period)) = t11._period))
Rows Removed by Join Filter: 503
-> GroupAggregate (cost=0.41..2.05 rows=1 width=27) (actual time=0.090..0.090 rows=1 loops=357742)
Group Key: t10._fld24519rref
-> Index Only Scan using _inforg24518_byperiod on _inforg24518 t10 (cost=0.41..2.03 rows=1 width=27) (actual time=0.021..0.090 rows=1 loops=357742)
Index Cond: ((_fld1077 = 137::numeric) AND (_period <= ‘2017-11-07 14:02:00’::timestamp without time zone) AND (_fld24519rref = ‘\\x80c3f9aa551a7ef811e7be6e3605cc38’::bytea))
Heap Fetches: 357742
-> Index Scan using _inforg24518_byperiod on _inforg24518 t11 (cost=0.41..2.03 rows=1 width=73) (actual time=0.010..0.140 rows=504 loops=357742)
-> Nested Loop (cost=0.57..5.05 rows=1 width=69) (actual time=0.009..0.009 rows=0 loops=1)
Join Filter: ((max(t4. _period)) = t5._period)
-> GroupAggregate (cost=0.29..2.52 rows=1 width=28) (actual time=0.008..0.008 rows=0 loops=1)
Group Key: t4._fld21037rref
-> Index Only Scan using _inforg21036_byperiod on _inforg21036 t4 (cost=0.29..2.51 rows=1 width=28) (actual time=0.008..0.008 rows=0 loops=1)
Index Cond: ((_fld1077 = 137::numeric) AND (_period <= ‘2017-11-07 14:02:00’::timestamp without time zone) AND (_fld21037rref = ‘\\x80c3f9aa551a7ef811e7be6e3605cc45’::bytea))
Heap Fetches: 0
-> Index Scan using _inforg21036_byperiod on _inforg21036 t5 (cost=0.29..2.50 rows=1 width=69) (never executed)
Index Cond: ((_fld1077 = 137::numeric) AND (_fld21037rref = ‘\\x80c3f9aa551a7ef811e7be6e3605cc45’::bytea))
-> Index Scan using _reference82hpk on _reference82 t12 (cost=0.28..2.50 rows=1 width=80) (actual time=0.000..0.000 rows=0 loops=1)
Index Cond: ((_fld1077 = 137::numeric) AND (t5._fld21040rref = _idrref))
Planning time: 5.606 ms
Execution time: 113484. 007 ms
‹ Частично зашифрованная база 1с на PostreSQL Восстановление базы 1C созданной на Postgresql-9.4.2 из папки base ›
postgresql — Как в psql запустить цикл для запроса Select с CTE и получить вывод, отображаемый в базе данных только для чтения?
РЕДАКТИРОВАТЬ: я создаю новый вопрос в соответствии с предложением из липкого бита.
У меня есть запрос с CTE для вывода результатов для нескольких значений (от 1 до 12). Ниже приведен упрощенный пример. Запустив его, я получил следующую ошибку:
ОШИБКА: запрос не имеет назначения для данных результатов
СОВЕТ: Если вы хотите отказаться от результатов SELECT, используйте вместо этого PERFORM.
КОНТЕКСТ: Функция PL/pgSQL inline_code_block строка 8 в операторе SQL
Я не могу вывести результат Select в таблицу. Как я могу решить эту проблему?
ДО $$ ОБЪЯВИТЬ r целое число; НАЧИНАТЬ г := 1; ПОКА г <= 2 ПЕТЛЯ г := г + 1; С параметрами КАК ( ВЫБЕРИТЕ r КАК номер строки ), время КАК ( ВЫБЕРИТЕ идентификатор Параметры FROM, анализ ЗАКАЗАТЬ ПО дате DESC ПРЕДЕЛ 1 OFFSET (ВЫБРАТЬ номер строки - 1 из параметров) ) ВЫБЕРИТЕ * ОТ времени; КОНЕЦ ПЕТЛИ; КОНЕЦ; $$;
- postgresql
- циклы
8
Пример того, что я упомянул в своем комментарии:
DO $$ ЗАЯВИТЬ г целое число; int_var целое число; НАЧИНАТЬ г := 1; ПОКА r <= 12 LOOP С параметрами КАК ( ВЫБЕРИТЕ r КАК номер строки ), время КАК ( ВЫБЕРИТЕ идентификатор Параметры FROM, анализ ЗАКАЗАТЬ ПО дате DESC ПРЕДЕЛ 1 OFFSET (ВЫБРАТЬ номер строки - 1 из параметров) ) SELECT INTO int_var id FROM time; ПОДНЯТЬ УВЕДОМЛЕНИЕ 'id: %', int_var; г := г + 1; КОНЕЦ ПЕТЛИ; КОНЕЦ; $$;
Вы не можете ВОЗВРАТИТЬ
значение из функции DO
, но вы можете ПОВЫШИТЬ УВЕДОМЛЕНИЕ
значение, как указано выше. SELECT INTO
устранит ошибку, поскольку вы указываете SELECT
пункт назначения ( int_var
) для его вывода. ПРИМЕЧАНИЕ : SELECT INTO
внутри plpgsql
отличается от той же команды снаружи. Внешне это эквивалентно
.
Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google
Зарегистрироваться через Facebook
Зарегистрируйтесь, используя адрес электронной почты и пароль
Опубликовать как гость
Электронная почта
Требуется, но никогда не отображается
Опубликовать как гость
Электронная почта
Требуется, но не отображается
Операторы цикла PL/pgSQL
Резюме : в этом руководстве вы узнаете об операторе цикла PL/pgSQL, который многократно выполняет блок кода.
Введение в PL/pgSQL Оператор цикла
Цикл
exit
или return
. Ниже показан синтаксис оператора цикла
:
Язык кода: диалект PostgreSQL SQL и PL/pgSQL (pgsql)
<<этикетка>> петля заявления; конечная петля;
Как правило, вы используете оператор if
внутри цикла, чтобы завершить его на основе следующего условия:
Язык кода: диалект PostgreSQL SQL и PL/pgSQL (pgsql)
<<метка>> петля заявления; если условие то выход; закончить, если; конечная петля;
Можно поместить оператор цикла внутри другого оператора цикла. Когда 9Оператор 0029 loop помещается внутри другого оператора loop
, он называется вложенным циклом:
Язык кода: диалект PostgreSQL SQL и PL/pgSQL (pgsql)
<
> петля заявления; <<внутренний>> петля /* ... */ выход <<внутренний>> конечная петля; конечная петля;
При наличии вложенных циклов необходимо использовать метку цикла, чтобы можно было указать ее в выходах
и оператор continue
, чтобы указать, к какому циклу относятся эти операторы.
Пример оператора цикла PL/pgSQL
В следующем примере показано, как использовать оператор цикла
для вычисления порядкового числа Фибоначчи.
Язык кода: диалект PostgreSQL SQL и PL/pgSQL (pgsql)
сделать $$ объявить n целое число:= 10; целое число := 0; целое число счетчика := 0 ; я целое := 0 ; j целое число := 1 ; начинать если (n < 1), то выдумка := 0 ; закончить, если; петля выйти, когда counter = n ; счетчик := счетчик + 1 ; выберите j, i + j в i, j ; конечная петля; выдумка := я; уведомление о повышении '%', выдумка; конец; $$
Вывод:
ПРИМЕЧАНИЕ: 55
Язык кода: HTTP (http)5 Номер блока целое число (
n
).