Сложный SQL, где предложение:стоит ли учитывать логику
-
16-09-2019 - |
Вопрос
У меня есть сложное предложение SQL, которое стало еще сложнее из-за изменения требований.Существует четыре основных набора случаев, каждый из которых имеет различное сочетание других факторов.Более читабельно (на мой взгляд) иметь четыре случая как отдельные ветви предложенияwhere и повторять избыточные критерии в каждой ветви.Но я не знаю, насколько хорошо механизм базы данных это оптимизирует.
Вот выражение в его избыточной форме.Я заменил фактические критерии буквами.A — критерий «ветвления», который существует в четырех формах.Все выражения имеют вид field='value'
, если иное не отмечено.
A1 AND B AND C AND D
OR A2 AND B AND C AND D AND E AND F1 AND G
OR A3 AND A3a AND B AND C AND D AND E AND F1 AND G
OR A4 AND B AND C AND D AND F2
Все буквы А, кроме А4, имеют форму field in ('value1','value2')
.D есть field > 'value'
.G имеет форму field not in (subquery)
.
Вот выражение, преобразованное в (я думаю) его наименее избыточную форму.
B AND C AND D AND (
A1
OR (
E AND F1 AND G AND (
A2
OR (A3 AND A3a)
)
)
OR (A4 AND F2)
Мой вопрос в том, следует ли мне разложить это выражение на самое простое (наименее избыточное) логичный форме, или можно ли сохранить ее в более избыточной, но при этом более читаемой форме.Целевой базой данных является Sybase, но мне хотелось бы знать ответ для RDMBS в целом.
Решение
В RDBMS
world Я бы не стал особо беспокоиться об избыточности, здесь важнее эффективность.
В твоем случае я бы UNION
все четыре запроса с использованием A
в качестве верхнего условия, например:
SELECT *
FROM mytable
WHERE A1 AND B AND C
UNION
SELECT *
FROM mytable
WHERE A2 AND B AND C AND D AND E AND F1 AND G
…
я не заглядывал Sybase
для более чем 7
лет, но во всех основных RDBMS
's UNION
более эффективны, чем OR
х.
См. эту статью в моем блоге, чтобы узнать о подходе к подобной проблеме в Oracle
:
- Выбор наименьшего значения:эффективное использование
UNION
вOracle
а также эта статья для сравнения UNION
против OR
в MySQL
:
- Выбор друзей:эффективность
UNION
по сравнению с одним изOR
вMySQL
Я думаю, что эти подходы будут хорошо работать для Sybase
слишком.
Вам также необходимо создать индексы для столбцов, используемых в ваших условиях, чтобы получить выгоду от UNION
's
Обновлять:
Поскольку условие G
является подзапросом, возможно, ему понадобится HASH JOIN
выполнять быстро. HASH JOIN
требуется полное сканирование всех нефильтрованных значений, поэтому, возможно, лучше отфильтровать все значения за одно полное сканирование, а затем выполнить HASH JOIN
:
SELECT *
FROM (
SELECT *
FROM foo
WHERE condition_set_1
UNION
SELECT *
FROM foo
WHERE condition_set_2_but_no_g
…
) q
WHERE G
Чтобы сделать какие-либо дальнейшие выводы, на самом деле будет гораздо лучше увидеть сам запрос.
Другие советы
Если бы я решал эту проблему на M$ SQL Server, я бы написал ее так, как хотел, и посмотрел бы на план выполнения запроса.Если бы он (а) работал медленно и (б) имел плохой план выполнения, я бы провел рефакторинг и документировал.Не уверен, какой в Sybase механизм просмотра того, КАК оптимизатор выполняет запрос.
Я бы провел рефакторинг.В конце концов, дублированная логика приведет к проблемам.Понимание второго примера может занять на пару секунд больше времени, но в большом объеме вещей легче увидеть, что происходит, поскольку вы можете быстро просмотреть весь операторwhere и начать определять, что на что влияет.