Оценка соединения "ИЛИ" в DB2 - PullRequest
3 голосов
/ 13 апреля 2020

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

(case
when field1 LIKE '%T001%' OR field1 LIKE '%T201%' OR field1 LIKE '%T301%'...

В приведенном выше утверждении, если field1 "like" t001, будут ли оцениваться другие?

(case
when (field1 LIKE '%T001%' OR field1 LIKE '%T201%' OR field1 LIKE '%T301%')...

Изменяет ли добавление круглых скобок, как показано выше, оценку?

Ответы [ 5 ]

1 голос
/ 13 апреля 2020

Вы не знаете.

SQL - это декларативный язык, а не императив . Вы описываете, что вы хотите, двигатель обеспечивает это. Механизм базы данных будет решать, в какой последовательности он будет оценивать эти предикаты, и вы не можете контролировать это.

Если вы получите план выполнения сегодня, он может показать одну последовательность шагов, но если вы ее получите завтра это может показать что-то другое.

1 голос
/ 13 апреля 2020

Строго не отвечая на ваш вопрос, но если у вас много таких совпадений, более простое, возможно, более быстрое и простое в обслуживании решение будет использовать REGEXP_LIKE. Пример, который вы разместили, можно написать так:

CASE WHEN REGEXP_LIKE(field1, '.*T(0|2|3)01.*') ...
1 голос
/ 13 апреля 2020

Как правило, базы данных замыкают логические операции. То есть они останавливаются на первом значении, определяющем результат - первом «true» для OR, первом «false» для AND.

При этом никаких гарантий нет. Также нет никаких гарантий относительно порядка оценки. Таким образом, DB2 может решить проверить среднее, последнее, а затем первое. Тем не менее, они довольно эквивалентны, поэтому я ожидал бы, что порядок будет либо первым, либо последним, либо последним, первым.

Помните: SQL является описательным языком, а не процедурный язык. Запрос SQL описывает набор результатов, но не шаги, используемые для его генерации.

0 голосов
/ 14 апреля 2020

Просто добавим к некоторым замечаниям о разнице между так называемыми процедурными языками, с одной стороны, и SQL (который по-разному описывается как декларативный или описательный язык), с другой.

SQL определяет набор операторов высокого уровня для работы с массивами данных. В этом смысле они являются «высокоуровневыми», потому что работают с массивами в сжатой форме, что не характерно для языков общего назначения или процедурных языков. Как и все операторы (независимо от того, основаны они на массивах или нет), обычно существует более одного алгоритма, способного реализовать оператор.

В отличие от языков программирования "общего назначения", с которыми сталкивается подавляющее большинство программистов, существование этих операторов массива - в частности, возможность объединять их алгебраически в выражение, которое определяет составную операцию (или запрос), и отсутствие каких-либо явных алгоритмов для итерации - когда-то было определяющей особенностью SQL.

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

Это Часто говорят, что в SQL вы определяете , какие результаты вы не хотите , как , чтобы получить их. Но это верно для каждого языка. Это верно даже для операторов машинного кода, если вы учитываете, как реализация в схемах может варьироваться - и действительно ли она варьируется в зависимости от конструкции ЦП. Это, безусловно, верно для всех скомпилированных языков, где компиляторы используют множество различных алгоритмов машинного кода для фактической реализации операций, указанных в исходном коде - l oop развертывание, например,

Функция, которая продолжает различаться guish SQL (и реляционные базы данных, которые его реализуют) заключается в том, что алгоритм, который реализует операцию, определяется во время каждого выполнения , и он делает это не только алгебраически c манипулирование запросами (что не отличается от того, что делают компиляторы), но также путем непрерывного генерирования и анализа статистики о данных, которые обрабатываются, и последствиях предыдущих выполнений.

Другими словами, механизм выполнения баз данных постоянно осуществляет поиск лучших практических алгоритмов (и их комбинаций) для реализации своей общей рабочей нагрузки. Он способен приспосабливаться не только к прошлому опыту, но и реагировать на изменения (например, в объемах данных, в степени параллелизма и транзакционного конфликта или в системных системных ограничениях c, таких как доступная память или общая рабочая нагрузка).

Результатом всего этого является то, что существует определенный c порядок оценки в SQL, как и на любом другом языке. Именно этот порядок определяет правильный результат. Но если написано не в так называемом стиле RBAR (и даже тогда, но в более ограниченной степени ...), ядро ​​базы данных обладает огромными возможностями для реализации ярлыков и оптимизации производительности, при условии, что они не изменяют конечный результат.

Многие операторы попадают в класс, где во многих случаях можно определить результат без оценки всех операндов. Я не уверен, что формальное слово, чтобы описать это свойство - частичная оценка , может быть, - но случайно это называется короткое замыкание . Оператор OR имеет это свойство.

Другое свойство операции OR состоит в том, что она ассоциативна . То есть порядок, в котором применяется ряд из них, не имеет значения - он ведет себя как оператор сложения, где вы можете добавлять числа в любом порядке, не влияя на результат.

С рядом условий ИЛИ они могут быть переупорядочены и частично оценены при условии, что оценка любого конкретного операнда не вызывает побочных эффектов или зависит от скрытых переменных. Поэтому вполне вероятно, что ядро ​​базы данных может изменить их порядок или частично оценить.

Если операнды вызывают побочные эффекты или зависят от скрытых переменных (функции, которые получают текущую дату или время, являющиеся основным примером последних), они часто вызывают проблемы в запросах - либо потому, что механизм базы данных делает не осознавать, что у них есть побочные эффекты или скрытые переменные, или потому что база данных действительно осознает это, но не обрабатывает случай так, как ожидает программист. В таких случаях запрос может быть полностью переписан (обычно разбит на несколько операторов), чтобы вызвать определенный c порядок оценки или гарантировать полную оценку.

0 голосов
/ 14 апреля 2020

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

select
  field1
, case
  when field1 LIKE '%T001%' OR RAISE_ERROR('75000', '%T201%') LIKE '%T201%' then 1 else 0
  end as expr
from 
(
values 
  'abcT001xyz'
--, '***'
) t (field1);

Запрос возвращает ожидаемый результат для вышеприведенного утверждения как есть. Но если вы раскомментируете закомментированную строку, вы получите SQLCODE=-438.
Это означает, что 2-й операнд ИЛИ не оценивается, если 1-й возвращает true.
Обратите внимание, что это только для демонстрации , Нет никакой гарантии, что это будет работать в любом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...