Выбираемая процедура очень медленная с отметкой времени - PullRequest
0 голосов
/ 10 марта 2019

У меня есть следующий оператор выбора:

SELECT
    "TRIP"."ID" as "ID",
    "TRIP"."KEY" as "TRIP_KEY",
    "ROUTE"."KEY" as "ROUTE_KEY",
    "ROUTE"."AGENCY_ID" as "AGENCY_ID",
    "TRIP"."BLOCK" as "BLOCK",
    "TRIP"."DIRECTION" as "DIRECTION",
    "CALENDAR"."MASK" as "MASK",
    "CALENDAR"."START_DATE",
    "CALENDAR"."END_DATE",
    "TRIP"."CALENDAR_ID" as "CALENDAR_ID"
    FROM "STOP_TIME" 
    JOIN "FEED" ON("STOP_TIME"."FEED_ID"="FEED"."ID") 
    JOIN "TRIP" ON ("STOP_TIME"."TRIP_ID"="TRIP"."ID") 
    JOIN "CALENDAR" ON("TRIP"."CALENDAR_ID"="CALENDAR"."ID") 
    JOIN "ROUTE" ON("TRIP"."ROUTE_ID"="ROUTE"."ID")
WHERE 
    "FEED"."REALTIME_FEED"='TrainFeed' AND 
    "FEED"."ACTIVE" = true AND 
    "CALENDAR"."START_DATE" <= '15.03.2019 11:00' AND 
    "CALENDAR"."END_DATE" >= '10.03.2019 11:00' AND
    "STOP_TIME"."DEPARTURE_TIME" >= 0 AND 
    "STOP_TIME"."DEPARTURE_TIME" < 39600000

, который дает мне следующее поведение во время выполнения (вывод из FlameRobin):

Выполнение оператора ...
Операторвыполнено (истекшее время: 0,000 с).
4287 выборок, 0 меток, 1847 чтений, 0 записей.
0 вставок, 0 обновлений, 0 удалений, 722 индекса, 3 сек.
Дельта-память: 1415008 байт.
Общее время выполнения: 0,322 с
Выполнение сценария завершено.

Однако, если я помещу этот запрос в выбираемую процедуру:

SET TERM ^ ;
CREATE PROCEDURE SELECT_TIMETABLE (
    FEEDNAME varchar(100),
    CALENDAR_TIME timestamp,
    TIME_FROM integer,
    TIME_TO integer)
RETURNS (
    ID bigint,
    TRIP_KEY varchar(100),
    ROUTE_KEY varchar(100),
    AGENCY_ID bigint,
    "BLOCK" varchar(100),
    DIRECTION smallint,
    MASK smallint,
    CALENDAR_ID bigint)
AS
DECLARE VARIABLE valid_trip BOOLEAN;
BEGIN 
    FOR SELECT
        "TRIP"."ID" as "ID",
        "TRIP"."KEY" as "TRIP_KEY",
        "ROUTE"."KEY" as "ROUTE_KEY",
        "ROUTE"."AGENCY_ID" as "AGENCY_ID",
        "TRIP"."BLOCK" as "BLOCK",
        "TRIP"."DIRECTION" as "DIRECTION",
        "CALENDAR"."MASK" as "MASK",
        "TRIP"."CALENDAR_ID" as "CALENDAR_ID"
    FROM "STOP_TIME" 
        JOIN "FEED" ON("STOP_TIME"."FEED_ID"="FEED"."ID") 
        JOIN "TRIP" ON ("STOP_TIME"."TRIP_ID"="TRIP"."ID") 
        JOIN "CALENDAR" ON("TRIP"."CALENDAR_ID"="CALENDAR"."ID") 
        JOIN "ROUTE" ON("TRIP"."ROUTE_ID"="ROUTE"."ID")
    WHERE 
        "FEED"."REALTIME_FEED"=:feedName AND 
        "FEED"."ACTIVE" = true AND 
        "CALENDAR"."START_DATE" <= :calendar_time AND 
        "CALENDAR"."END_DATE" >= :calendar_time AND 
        "STOP_TIME"."DEPARTURE_TIME" >= :time_from AND 
        "STOP_TIME"."DEPARTURE_TIME" < :time_to
    INTO :id, :trip_key, :route_key, :agency_id, :block, :direction, :mask, :calendar_id DO 
    BEGIN
        SUSPEND;
    END
END^
SET TERM ;

и вызывать его с теми же параметрами:

SELECT 
    p.ID, p.TRIP_KEY, 
    p.ROUTE_KEY, 
    p.AGENCY_ID, 
    p."BLOCK", 
    p.DIRECTION,
    p.MASK, p.CALENDAR_ID
FROM SELECT_TIMETABLE (
    'TrainFeed', 
    '15.03.2019 11:00', 
    0, 
    39600000) p;

Я получаю гораздо худшее поведение во время выполнения:

Выполнение оператора ...
Выполнение оператора (истекшее время: 0,000s).
3248968 выборок, 0 отметок, 52540 операций чтения, 0 записей.
0 вставок, 0 обновлений, 0 удалений, 1338852 индекса, 42 секв.
Дельта-память: 784 байта.
Общее время выполнения: 3,477 с
Выполнение сценария завершено.

Я сузил его до фильтрации START_DATE и END_DATE таблицы CALENDAR.Если я пропущу фильтр, время выполнения уменьшится до половины секунды.В дополнение к этому, процедура выбора, представленная выше, также не дает никаких результатов (с фильтрацией START_DATE / END_DATE), где выполняется запрос.

Так что, похоже, что-то не так с моей выбираемой процедурой.Но я не вижу проблемы.

Версия Firebird - 3.0.4.33054 (x64) для Windows.В настоящее время я использую Firebird в качестве встроенного сервера.

...