Начало » Использование СУБД » PostgreSQL » Отличие времени выполнения обычного запроса и обёрнутого в функцию
Отличие времени выполнения обычного запроса и обёрнутого в функцию [сообщение #4527] |
Sun, 25 February 2024 14:38 |
rick1177
Сообщений: 2 Зарегистрирован: February 2024
|
Junior Member |
|
|
Ребят, привет.
Я совсем но новичок, но очень стараюсь.
Помогите, пожалуйста, разобраться в вопросе.
У меня есть обычный селект такого вида:
EXPLAIN ANALYZE
(SELECT ogrn,
current_loc_name_region,
CASE WHEN is_ikt IS NOT NULL THEN 1 ELSE 0 END AS is_ikt,
is_it_group,
registrationdate,
EXTRACT(YEAR FROM registrationdate) as registrationdate_year,
EXTRACT(QUARTER FROM registrationdate) as registrationdate_quarter,
EXTRACT(MONTH FROM registrationdate) as registrationdate_month,
(date_trunc('MONTH', registrationdate))::date AS registrationdate_month_year_start,
(date_trunc('MONTH', registrationdate) + INTERVAL '1 MONTH' -
INTERVAL '1 day')::date AS registrationdate_month_year_end,
issuedate,
EXTRACT(YEAR FROM issuedate) as issuedate_year,
EXTRACT(QUARTER FROM issuedate) as issuedate_quarter,
EXTRACT(MONTH FROM issuedate) as issuedate_month,
(date_trunc('MONTH', issuedate))::date AS issuedate_month_year_start,
(date_trunc('MONTH', issuedate) + INTERVAL '1 MONTH' - INTERVAL '1 day')::date AS issuedate_month_year_end,
termination_date,
EXTRACT(YEAR FROM termination_date) as termination_date_year,
EXTRACT(QUARTER FROM termination_date) as termination_date_quarter,
EXTRACT(MONTH FROM termination_date) as termination_date_month,
(date_trunc('MONTH', termination_date))::date AS termination_date_month_year_start,
(date_trunc('MONTH', termination_date) + INTERVAL '1 MONTH' -
INTERVAL '1 day')::date AS termination_date_month_year_end,
main_okved,
main_okved_desc,
address_rf_code,
address_fr_regionname,
address_rf_okrug,
address_rf_okrug_full,
ROW_NUMBER() OVER (PARTITION BY ogrn ORDER BY issuedate DESC) AS rn
FROM egrul_egrip_test.egrul_wdiffs
WHERE issuedate <=
DATE_TRUNC('MONTH', to_date(2023::text || '-' || 12::text || '-01', 'YYYY-MM-DD')) + INTERVAL '1 MONTH' -
INTERVAL '1 day'
)
На моей таблице этот товарищ выполняется 2 мин 36 сек. Меня вполне устраивает.
Дальше я бы хотел преобразовать этот запрос в функцию и выполнить и засечь время выполнения.
Выглядит это так (включая вызов):
DROP FUNCTION IF EXISTS get_table_data(text, int, int);
CREATE OR REPLACE FUNCTION get_table_data(
_tablename text DEFAULT 'egrul_wdiffs',
_year int DEFAULT 2023,
_month int DEFAULT 12)
RETURNS TABLE (
ogrn TEXT,
current_loc_name_region TEXT,
is_ikt INT,
is_it_group character varying,
registrationdate DATE,
registrationdate_year DOUBLE PRECISION,
registrationdate_quarter DOUBLE PRECISION,
registrationdate_month DOUBLE PRECISION,
registrationdate_month_year_start DATE,
registrationdate_month_year_end DATE,
issuedate DATE,
issuedate_year DOUBLE PRECISION,
issuedate_quarter DOUBLE PRECISION,
issuedate_month DOUBLE PRECISION,
issuedate_month_year_start DATE,
issuedate_month_year_end DATE,
termination_date DATE,
termination_date_year DOUBLE PRECISION,
termination_date_quarter DOUBLE PRECISION,
termination_date_month DOUBLE PRECISION,
termination_date_month_year_start DATE,
termination_date_month_year_end DATE,
main_okved character varying,
main_okved_desc character varying,
address_rf_code character varying,
address_fr_regionname TEXT,
address_rf_okrug TEXT,
address_rf_okrug_full TEXT,
rn BIGINT
) AS
$$
BEGIN
RETURN QUERY
SELECT
egrul_wdiffs.ogrn,
egrul_wdiffs.current_loc_name_region,
CASE WHEN egrul_wdiffs.is_ikt IS NOT NULL THEN 1 ELSE 0 END AS is_ikt,
egrul_wdiffs.is_it_group,
egrul_wdiffs.registrationdate,
EXTRACT(YEAR FROM egrul_wdiffs.registrationdate) as registrationdate_year,
EXTRACT(QUARTER FROM egrul_wdiffs.registrationdate) as registrationdate_quarter,
EXTRACT(MONTH FROM egrul_wdiffs.registrationdate) as registrationdate_month,
(date_trunc('MONTH', egrul_wdiffs.registrationdate))::date AS registrationdate_month_year_start,
(date_trunc('MONTH', egrul_wdiffs.registrationdate) + INTERVAL '1 MONTH' - INTERVAL '1 day')::date AS registrationdate_month_year_end,
egrul_wdiffs.issuedate,
EXTRACT(YEAR FROM egrul_wdiffs.issuedate) as issuedate_year,
EXTRACT(QUARTER FROM egrul_wdiffs.issuedate) as issuedate_quarter,
EXTRACT(MONTH FROM egrul_wdiffs.issuedate) as issuedate_month,
(date_trunc('MONTH', egrul_wdiffs.issuedate))::date AS issuedate_month_year_start,
(date_trunc('MONTH', egrul_wdiffs.issuedate) + INTERVAL '1 MONTH' - INTERVAL '1 day')::date AS issuedate_month_year_end,
egrul_wdiffs.termination_date,
EXTRACT(YEAR FROM egrul_wdiffs.termination_date) as termination_date_year,
EXTRACT(QUARTER FROM egrul_wdiffs.termination_date) as termination_date_quarter,
EXTRACT(MONTH FROM egrul_wdiffs.termination_date) as termination_date_month,
(date_trunc('MONTH', egrul_wdiffs.termination_date))::date AS termination_date_month_year_start,
(date_trunc('MONTH', egrul_wdiffs.termination_date) + INTERVAL '1 MONTH' - INTERVAL '1 day')::date AS termination_date_month_year_end,
egrul_wdiffs.main_okved,
egrul_wdiffs.main_okved_desc,
egrul_wdiffs.address_rf_code,
egrul_wdiffs.address_fr_regionname,
egrul_wdiffs.address_rf_okrug,
egrul_wdiffs.address_rf_okrug_full,
ROW_NUMBER() OVER (PARTITION BY egrul_wdiffs.ogrn ORDER BY egrul_wdiffs.issuedate DESC) AS rn
FROM
egrul_egrip_test.egrul_wdiffs
WHERE
egrul_wdiffs.issuedate <= DATE_TRUNC('MONTH', DATE(_year || '-' || _month || '-01')) + INTERVAL '1 MONTH' - INTERVAL '1 day';
END;
$$
LANGUAGE 'plpgsql';
EXPLAIN ANALYZE (
SELECT *
FROM get_table_data( _year := 2023));
Казалось бы, всё идентично, но это действие выполняется 9 минут и 18 сек.
Мой вопрос, наконец )
Почему время выполнения разное?
Мне казалось это одно и то же.
Или я что-то делаю не так?
|
|
|
|
|
|
Переход к форуму:
Текущее время: Thu Nov 21 15:40:26 GMT+3 2024
Общее время, затраченное на создание страницы: 0.00640 секунд
|