14.01.2011 16:56, Александр Свириденков пишет:
После пересчета статистики, первый запрос и правда стал давать
нормальный план
PLAN JOIN (CR INDEX (PK_CONT_RES), CT INDEX (RDB$PRIMARY13))
Ну и замечательно.
Но если в него поставить cr.resource is null то один фиг получаем
полное чтение CONT_RES по индексу
Т.е. речь про:
select * from cont_res cr join contracts ct on cr.cont_id=ct.cont_id
where cr.serv_id=14 and cr.resource is null
?
И тут же получаем полное индексированное чтение CONT_RES
Так полное или индексированное?
По индексу, но количество чтений=количеству записей в таблице
Кажется, картина проясняется. См. ниже.
Была бы сермяжная правда в твоих словах, если бы при попытке удалить
PK использующийся в препарированном
запросе, не получал бы со 100% вероятностью Object ... in use
Так что вы уж или крестик снимите...(с) :)
Твоя правда :-) Кстати, NOT NULL ты таки снять можешь (если там UK, а не
PK). Но не удалить PK, это да.
Кроме того, мне казалось что с какой-то версии FB уже умеет искать
NULL по индексу
Он всегда это умел. Просто раньше там проблемы были.
Насколько я понимаю, тут засада в композитном индексе, где NULL - не
последний сегмент. Я недавно это объяснял Болтику, цитирую:
"Это особенность реализации нуллов в индексах. Для ASC-индексов нуллы
хранятся как ключи нулевой длины. Поэтому при поиске на частичное
соответствие (полей в индексе больше чем в запросе) нулл будет равен
любому другому ключу. Аналогия для индекса с 4 сегментами:
A = a and B = b and C = c : field like 'abc%'
A = a and B = b and C is null : field like 'ab%'
т.е. нулл после сегмента B есть, но его при поиске не видно, т.к. это
ключ нулевой длины. Отсюда и шире выборка, больше чтений."
Таким образом, де-факто имеем поиск лишь по первому сегменту
композитного индекса, а им выбираются все 100% значений.
Попробуй пересоздать композитный PK как DESC-индекс. В этом случае нуллы
хранятся в виде 0xFF и все должно работать как ожидается.
Ну, или если ты заранее знаешь, что эта выборка по PK фиктивная, то
добавь в предикат для CONT_RES любое значения столбца CONT_ID, тогда
индексный ключ станет полным и нуллы начнут искаться (и не находиться).
Дмитрий