При переходе с Yaffil на ФБ заметили "странное" поведение запросов с
left join stored_poc
проверялось на фб 2.0.2, 2.0.3 и 2.1.16459 Firebird 2.1 Beta 1
Пример базы:
Версия ОДС 11.1
Размер страницы 8192
Размер файла БД 90 MB
SET SQL DIALECT 3;
SET NAMES WIN1251;
CREATE TABLE GD_GOOD (ID INTEGER NOT NULL, USR$MN_MAINGOODKEY
INTEGER);
ALTER TABLE GD_GOOD ADD CONSTRAINT PK_GD_GOOD PRIMARY KEY (ID);
CREATE INDEX GD_GOOD_IDX1 ON GD_GOOD (USR$MN_MAINGOODKEY);
CREATE TABLE INV_MOVEMENT (ID INTEGER NOT NULL, MOVEMENTDATE DATE,
CONTACTKEY INTEGER, GOODKEY INTEGER);
ALTER TABLE INV_MOVEMENT ADD CONSTRAINT PK_INV_MOVEMENT PRIMARY KEY
(ID);
CREATE DESCENDING INDEX INV_MOVEMENT_IDX1 ON INV_MOVEMENT
(MOVEMENTDATE);
CREATE DESCENDING INDEX INV_MOVEMENT_IDX2 ON INV_MOVEMENT (GOODKEY,
CONTACTKEY, MOVEMENTDATE);
CREATE PROCEDURE USR$INV_GETREMAINS (goodkey integer, contactkey
integer, movementdate date) returns (mdate date)
as
begin
for
select first(1) m.movementdate from
inv_movement m
where
m.goodkey = :goodkey
and m.contactkey = :contactkey
and m.movementdate <= :movementdate
order by
m.movementdate desc
into :mdate
do
begin
suspend;
end
end
Селективность индексов:
gd_good
ПК Индекс На поле Выражение Уникальный Активность Тип сортировки
Статистика
0 GD_GOOD_IDX1 USR$MN_MAINGOODKEY 0 1 По возрастанию
0,000288433802779763937
1 PK_GD_GOOD ID 1 1 По возрастанию 0,000170765022630803287
inv_movement
ПК Индекс На поле Выражение Уникальный Активность Тип сортировки
Статистика
0 INV_MOVEMENT_IDX1 MOVEMENTDATE 0 1 По убыванию
0,00291545200161635876
0 INV_MOVEMENT_IDX2 GOODKEY,CONTACTKEY,MOVEMENTDATE 0 1 По убыванию
0,00000129859336084336974
1 PK_INV_MOVEMENT ID 1 1 По возрастанию 0,000000885739609657321125
Кол-во записей:
inv_movement - 1129000
gd_good - 5856
Выполнение запроса с процедурой:
select
g.id
from
gd_good g
left join usr$inv_getremains( g.id, :contactkey, :movementdate) b on
1 = 1
where
g.usr$mn_maingoodkey = :USR$MAINGOODKEY
План
PLAN JOIN (G INDEX (GD_GOOD_IDX1), M ORDER INV_MOVEMENT_IDX1 INDEX
(INV_MOVEMENT_IDX2))
Адаптированный план
PLAN JOIN (G INDEX (GD_GOOD_IDX1), M ORDER INV_MOVEMENT_IDX1 INDEX
(INV_MOVEMENT_IDX2))
------ Performance info ------
Prepare time = 0ms
Execute time = 1s 110ms
Avg fetch time = 111,00 ms
Current memory = 17 485 228
Max memory = 17 786 000
Memory buffers = 2 048
Reads from disk to cache = 0
Writes from cache to disk = 0
Fetches from cache = 5 109
Удивляет долгое выполнение запроса по сравнению со схожим запросом :
Выполнение запроса с вложенным селктом :
select
g.id
from
gd_good g
left join (SELECT first(1) m.goodkey, m.contactkey, m.movementdate
FROM
inv_movement m
ORDER by
m.movementdate desc) b on
b.goodkey = g.id
and b.contactkey = :contactkey
and b.movementdate <= :MovementDate
where
g.usr$mn_maingoodkey = :USR$MAINGOODKEY
План
PLAN JOIN (G INDEX (GD_GOOD_IDX1), B M ORDER INV_MOVEMENT_IDX1)
Адаптированный план
PLAN JOIN (G INDEX (GD_GOOD_IDX1), B M ORDER INV_MOVEMENT_IDX1)
------ Performance info ------
Prepare time = 0ms
Execute time = 0ms
Avg fetch time = 0,00 ms
Current memory = 17 487 168
Max memory = 17 786 000
Memory buffers = 2 048
Reads from disk to cache = 0
Writes from cache to disk = 0
Fetches from cache = 75
Если отключить индекс inv_movement по movementdate
то результат первого запроса:
План
PLAN JOIN (G INDEX (GD_GOOD_IDX1), SORT (M INDEX (INV_MOVEMENT_IDX2)))
Адаптированный план
PLAN JOIN (G INDEX (GD_GOOD_IDX1), SORT (M INDEX (INV_MOVEMENT_IDX2)))
------ Performance info ------
Prepare time = 16ms
Execute time = 0ms
Avg fetch time = 0,00 ms
Current memory = 17 487 248
Max memory = 17 625 028
Memory buffers = 2 048
Reads from disk to cache = 0
Writes from cache to disk = 0
Fetches from cache = 994
второго
План
PLAN JOIN (G INDEX (GD_GOOD_IDX1), SORT (B M NATURAL))
Адаптированный план
PLAN JOIN (G INDEX (GD_GOOD_IDX1), SORT (B M NATURAL))
------ Performance info ------
Prepare time = 0ms
Execute time = 38s 94ms
Avg fetch time = 3 809,40 ms
Current memory = 17 489 228
Max memory = 76 211 692
Memory buffers = 2 048
Reads from disk to cache = 85 491
Writes from cache to disk = 0
Fetches from cache = 22 751 155
С уважением, Леонид Агафонов