Оптимизация SQL-запросов Firebird

У меня есть большая таблица БД (> 300 000 записей), и я хочу запрашивать поля в соответствии с одним параметром без объединений следующим образом:

SELECT F1, F2, ..., IS_NOT_TO_LOAD FROM MY_TABLE WHERE IS_NOT_TO_LOAD IS DISTINCT FROM 1;

Я создал индекс в таблице w.r.t. IS_NOT_TO_LOAD поле:

CREATE ASC INDEX "IND_MY_TABLE_IS_NOT_TO_LOAD" ON "MY_TABLE" ("IS_NOT_TO_LOAD");

Я не очень хорошо знаком с планами выполнения, но я ожидаю, что запрос будет использовать план индекса, а не естественный план выполнения.

Я делаю что-то не так, или есть лучший подход для оптимизации моего запроса?

ОБНОВЛЕНИЕ Я обнаружил, что с помощью следующего запроса:

SELECT F1, F2, ..., IS_NOT_TO_LOAD FROM MY_TABLE WHERE IS_NOT_TO_LOAD < 1;

использует план PLAN (A INDEX (IND_MY_TABLE_IS_NOT_TO_LOAD)), но я не использовал его, потому что иногда у меня есть 0 или нулевые значения, иногда 0


person neggenbe    schedule 24.11.2016    source источник
comment
Что дает IS_NOT_TO_LOAD is null or IS_NOT_TO_LOAD <> 1? Обратите внимание, что это звучит как колонка с низкой избирательностью, так что это может быть причиной того, что Firebird предпочитает не использовать индекс.   -  person Mark Rotteveel    schedule 25.11.2016
comment
@MarkRotteveel то же самое - он использует естественный план ...   -  person neggenbe    schedule 25.11.2016


Ответы (1)


Запрос может быть быстрым, только если предложение WHERE может использовать первичный ключ или индекс (поля в WHERE должны существовать в INDEX). У вас нет такого случая, поэтому Firebird должен прочитать все записи из таблицы, чтобы определить, какая из них соответствует предложению WHERE. Я предлагаю использовать индекс из вашего вопроса, но сначала убедитесь, что у вас нет IS_NOT_TO_LOAD = null (сейчас и в будущем).

person Daniel Vidić    schedule 01.01.2017