Как получить индекс, используемый с оператором OR in

У меня есть SQL с параметрами, переданными пользователем. Пользователь может передать какой-нибудь идентификатор или -1, что означает «неважно». Можно написать запрос, как показано ниже, но можно ли использовать индекс?

SELECT *
FROM table
WHERE
    ((col1 = :param1) OR (:param1 = -1))
    AND ((col2 = :param2) OR (:param2 = -1))
    AND col3 STARTING 'A'

col1, col2 и col3 проиндексированы. В FB 2.x с использованием OR никогда не используйте index для col1 или col2. В FB 3, только если существуют первые (или вторые) условия, которые могут использовать индекс (индекс PLAN и естественный), но с последним условием прекращают использование индекса для col1 / 2.

Как я могу написать SQL без использования PLAN и могу использовать индекс для col1/2 и оставить возможность «выключить» состояние, передав -1?

почему бы не построить другой SQL для запроса на клиенте (или даже в SP) на основе параметров фильтра?

Arioch 'The 30.08.2018 10:48

SQL пишется в интерфейсе (а не в коде) и должен быть универсальным. Что-то вроде IBExpert, но SQL написал один раз (например, суперпользователем) и не будет менять при каждом использовании с разными параметрами.

Dżyszla 30.08.2018 10:58

Вариантом может быть включение логики в EXECUTE BLOCK ...

cincura.net 30.08.2018 13:10

@ Dżyszla. . . Создайте предложение where динамически и добавьте его в запрос. Условия с or намного сложнее оптимизировать, чем условия только с and.

Gordon Linoff 30.08.2018 13:20

предоставить суперпользователю возможность предоставлять варианты частей sql. Или конструктор как в IBExpert

Arioch 'The 30.08.2018 13:23

Нет, нет ... Суперпользователь создает какой-то запрос. Сборка приложения для этого (на основе параметров запроса) интерфейса, использующего "обычного" пользователя. Один раз суперпользовательский запрос на запись и хочет дать другим возможность указать (> 0) или нет (-1) фильтр. Поэтому необходимо создать запрос для обоих случаев.

Dżyszla 30.08.2018 14:18

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

Arioch 'The 30.08.2018 15:39

PS AFAIR можно явно указать план выполнения в операторе SQL, но тогда не будет никакой гарантии, что пользовательский план будет оптимальным или правильным. В конце концов, вы производите сортировку по столбцам три, неясно, что объединение индексов №1 и №2, а затем сканирование nat по col3 всегда будет лучше, чем сначала сокращение на col3, а затем nat-сканирование по col1 и col2

Arioch 'The 30.08.2018 15:42
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
8
55
1

Ответы 1

Вы можете переписать условие вроде

(col1 = :param1) OR (:param1 = -1)

в виде

col1 = case when :param1 = -1 then col1 else :param1 end

Поскольку это одно выражение, вы также можете безопасно удалить все скобки, что упростит чтение запроса.

Еще ПЛАНИРУЙТЕ (НАТУРАЛЬНО) и прочтите все записи - это не работает в Firebird :(

Dżyszla 30.08.2018 09:10

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

Gordon Linoff 30.08.2018 13:19

Другие вопросы по теме