SQLRU.net
Разработка приложений баз данных

Начало » Использование СУБД » PostgreSQL » Отличие времени выполнения обычного запроса и обёрнутого в функцию
Отличие времени выполнения обычного запроса и обёрнутого в функцию [сообщение #4527] Sun, 25 February 2024 14:38 Переход к следующему сообщению
rick1177 в настоящее время не в онлайне  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 сек.

Мой вопрос, наконец )
Почему время выполнения разное?
Мне казалось это одно и то же.
Или я что-то делаю не так?
Re: Отличие времени выполнения обычного запроса и обёрнутого в функцию [сообщение #4542 является ответом на сообщение #4527] Mon, 26 February 2024 13:42 Переход к предыдущему сообщениюПереход к следующему сообщению
BlackEric в настоящее время не в онлайне  BlackEric
Сообщений: 360
Зарегистрирован: June 2022
Senior Member
Вам нужно смотреть план запроса в обоих случаях и что в нем меняется.
Re: Отличие времени выполнения обычного запроса и обёрнутого в функцию [сообщение #4550 является ответом на сообщение #4542] Mon, 26 February 2024 16:31 Переход к предыдущему сообщениюПереход к следующему сообщению
rick1177 в настоящее время не в онлайне  rick1177
Сообщений: 2
Зарегистрирован: February 2024
Junior Member
Подскажите, пожалуйста, как?
Re: Отличие времени выполнения обычного запроса и обёрнутого в функцию [сообщение #4553 является ответом на сообщение #4550] Tue, 27 February 2024 11:34 Переход к предыдущему сообщению
BlackEric в настоящее время не в онлайне  BlackEric
Сообщений: 360
Зарегистрирован: June 2022
Senior Member
14.1. Использование EXPLAIN

И там ещё много документации...
Предыдущая тема: Написать странный запрос с update
Следующая тема: Как вывести в запросе классифицируемое понятие
Переход к форуму:
  


Текущее время: Thu Nov 21 15:40:26 GMT+3 2024

Общее время, затраченное на создание страницы: 0.00640 секунд