У меня есть следующий оператор выбора:
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 в качестве встроенного сервера.