2015-06-05 1 views
3

Я застрял с оптимизацией этого SQL-запроса в реляционной алгебры:Застрял с Logical SQL оптимизации запросов в реляционной алгебре (OR в WHERE)

SELECT * FROM R1, R2, R3, R4 
WHERE (R1.A = '1' OR (R2.B = '2' AND R3.C = R4.C)) AND R4.D = '4' 

Я перевел его к следующему утверждению реляционной алгебры:

σ{R1.A='1' ∨ (R2.B='2' ∧ R3.C=R4.C) ∧ R4.D='4'}(R1 × R2 × R3 × R4) 

Моя проблема в том, что я не знаю, как оптимизировать оператор where. Я знаю, что могу преобразовать последнее условие в σ{R4.D='4'}(R4) и перенести его вниз по дереву непосредственно на R4. Существуют определенные правила оптимизации, однако я действительно не знаю, как обращаться с OR. Rules for Logical Query Optimization

Но как я могу оптимизировать остальные места? Я думал об использовании распределительных правило, чтобы превратить его в КНФ,

(R1.A='1' ∨ R2.B='2') ∧ (R1.A='1' ∨ R3.C=R4.C) 

, который позволил бы мне обрабатывать оба положение независимо друг от друга. Но я не буду продолжать, особенно в каком порядке я должен присоединиться или сделать декартовую продукцию.

Вот оператор-дерево, я рисую: OperatorTree

+0

Что именно вы имеете в виду "оптимизации"? И что это связано с SQLite? –

+0

@CL Оптимизация означает использование логических правил реляционной алгебры, чтобы уменьшить стоимость оценки и оптимизировать порядок запросов операторов, например. переместите выделение до упора до конца. С меткой sqlite, поскольку SQL-синтаксис предназначен для sqlite (я использую sqlite как систему db) Примеры: http://www.cs.uni-paderborn.de/ fileadmin/Informatik/AG-Boettcher/Lehre/WS_07_08/dbis1/dbis1k2-logic-query-optimization.pdf –

+3

Возможно, я ошибаюсь, но в вашем переводе вы опустили одну пару скобок. В исходном запросе у вас есть: '(R1.A = '1' OR (R2.B = '2' AND R3.C = R4.C)) AND R4.D = '4'' , который должен дать вам : '(R1.A = '1' ∨ (R2.B = '2' ∧ R3.C = R4.C)) ∧ R4.D = '4'' –

ответ

1

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

Solution for the problem

1

Хороший способ борьбы с дизъюнкции во время оптимизации запросов, чтобы преобразовать условие выбора в дизъюнктивной нормальной форме (ДНФ), а затем переписать выбор в Союз выборов (по одному на дизъюнкт).

I.e. примените правило № 2 здесь: https://en.wikipedia.org/wiki/Relational_algebra#Breaking_up_selections_with_complex_conditions

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

+1

Но операнды UNION должны иметь тот же набор столбцов. DNF не гарантирует этого. (Т. Е. Его ORs не сопоставляются с UNION.) С этим вопросом недостаточно информации, чтобы удовлетворить это, если вы НЕ СОЕДИНЯете два соединения всех отношений, которые не будут оптимизацией. (См. Мой комментарий к вопросу.) – philipxy

+0

С этим правилом перезаписи вы должны СОЕДИНЯТЬ два объединения всех отношений (в противном случае вы получите неправильный результат). I.e. исходным запросом будет: SELECT * FROM R1, R2, R3, R4 WHERE (R1.A = '1' AND R4.D = '4') UNION SELECT * FROM R1, R2, R3, R4 (R2.B = '2' AND R3.C = R4.C AND R4.D = '4') В этом случае это не оптимизация (отсюда и мой отказ от ответственности в ответе), но после перезаписи это гораздо проще увидеть, что запрос запрашивает серию декартовых произведений, поэтому для его оптимизации не так много. –

+0

Ваш комментарий просто повторяет мой комментарий, поэтому я не знаю, почему вы написали свой комментарий. Более того, если в моем комментарии здесь вы прочтете мой комментарий по вопросу, вы обнаружите, что оптимизация начального запроса возможна путем сопоставления ∨ с ∨ в выборе/ограничении, а не в U. LIke в правильном ответе, который только что опубликовал Кристоф С. (И не по некорректному, с которым он связал комментарий ранее.) – philipxy