Глюки в планах.

Access Violation, некорректное выполнение запросов или вызовов API, ошибки утилит командной строки, в общем все, что вам мешает работать

Модераторы: kdv, dimitr

Ответить
_so_
Сообщения: 144
Зарегистрирован: 04 ноя 2004, 22:17

Глюки в планах.

Сообщение _so_ » 22 дек 2004, 13:55

Проблема которая появилась в IB7.1. Осталась и Ib7.5. ЭЭтим людям из Borland похоже совсем наплевать на замечания. В кратце напомню:
После перехода на IB 7.1 SP1
во вложенных select перестали использоваться индексы. В результате жуткие тормоза.

Попробовал состряпать простой пример:

Код: Выделить всё

Метадынные:

CREATE TABLE TABLE_TEST1 (
    FIELD1 INTEGER NOT NULL,
    FIELD2 INTEGER
    );

CREATE TABLE TABLE_TEST2 (
    FIELD1 INTEGER,
    FIELD2 INTEGER,
    FIELD3 INTEGER);
/* Indices definition */

CREATE INDEX TABLE_TEST2_IDX1 ON TABLE_TEST2 (FIELD2);

Запрос:
select T1.* from table_test1 T1
where
T1.FIELD2-ABS((Select Sum(T2.Field1) from table_test2 T2
       where T2.Field2 = T1.Field1))>0

Получаем план в 7.1
PLAN (T2 INDEX (TABLE_TEST2_IDX1))PLAN (T2 NATURAL)PLAN (T1 NATURAL)

Выполняем в 7.0

получаем план:
PLAN (T2 INDEX (TABLE_TEST2_IDX1))PLAN (T2 INDEX (TABLE_TEST2_IDX1))PLAN (T1 NATURAL)

Еще я не понимаю почему из-за UDF получаем два плана на вложенный
запрос. Если убрать использование udf (ABS), то получаем только один
вложенный план причем правильный ив IB7.1. Но в конкретном случае без
использования udf нельзя, так как null не должен появляться (если
вложенный запрос ничего не нашел).
На IB 7.5 ситуация повторяется.
Прийтеся по прежнему udf обертывать хранимой процедурой:

Код: Выделить всё

select T1.* from table_test1 T1
where
T1.FIELD2 - (select Summa from ABS_((Select Sum(T2.Field1) from table_test2 T2 where T2.Field2 = T1.Field1)))>0

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Сообщение dimitr » 22 дек 2004, 20:27

Насчет двойного плана на подзапросы внутри UDF - там банальная бага в SQL-компиляторе, я ее исправил в FB2 (пытался в 1.5.1, но там бяка вылезла). Т.е. так было всегда, но оно никогда никому особо не мешало. Но борманы что-то отломили в оптимайзере в 7.1, после чего планы подзапросов внутри UDF стали не идентичными. А т.к. реально используется только один из них, то случай во-видимому указывает на худший.

Сделать тут ничего нельзя. Либо добивай борманов - пусть 3.14здят у нас очередной багфикс, либо избавляйся от UDF. Начиная с 7.5, наверное можешь заюзать COALESCE для избавления от NULLов.

Ответить