Оптимизация SQL и дизъюнктивная нормальная форма

Итак, я писал запрос в Visual Studio 2010 (я имею в виду, что я открыл проводник сервера, щелкнул правой кнопкой мыши сервер и выбрал «Новый запрос»). В запросе есть условие

A AND B AND C AND D AND E AND F AND (G OR H)

что является конъюнктивной нормальной формой (CNF). Когда я выполнил запрос (прикрепленный к MSSQL Server 2008), он изменил текст на

A AND B AND C AND D AND E AND F AND G OR
A AND B AND C AND D AND E AND F AND H

что является дизъюнктивной нормальной формой (ДНФ).

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

Однако для чего-то подобного, с таким количеством повторяющихся условий, действительно ли DNF дает преимущество перед CNF? Если это не так, как я могу заставить оптимизатор принять условие как есть? Если это так, должен ли я написать запрос в коде моего приложения в форме CNF, потому что он короче и аккуратнее, или в форме DNF, потому что это экономит время для оптимизатора?


person Jodaka    schedule 25.07.2011    source источник
comment
Где он изменил текст запроса? Можете ли вы опубликовать скриншот?   -  person Justin    schedule 25.07.2011
comment
К сожалению, нет простого способа опубликовать скриншот (компьютеры на работе странные). Что касается первого вопроса, я был на вкладке запроса в VS2010 (где есть четыре панели: диаграмма, критерии, SQL, результаты), и он перезаписал SQL, который я написал, новым текстом.   -  person Jodaka    schedule 25.07.2011
comment
Я никогда не изучал какие-либо конкретные реализации механизмов SQL, кроме своих собственных. ^^ Поэтому я не знаю, будет ли ускорено фактическое выполнение запроса через DNF. Что я МОГУ сказать, так это то, что DNF — это как минимум интересный подход к кэшированию. Механизм SQL может преобразовать запрос в DNF, чтобы иметь возможность проверить, выполнялся ли запрос ранее. И если это так, возможно, переводы запросов из SQL в собственные представления или даже результаты запросов могут быть доставлены из кеша. Но я согласен с Clockwork-Muse и оставил бы это на усмотрение движка SQL, а сам написал бы читаемый запрос.   -  person user573215    schedule 23.10.2013
comment
Visual Studio 2012 Query Builder (при разработке TableAdapter) преобразовал мое предложение SQL where в нормальную форму. Есть ли настройка для отключения этого поведения?   -  person isti_spl    schedule 26.01.2014
comment
Ну, я в недоумении... Я никогда не слышал о DNF. Я также никогда не знал, что SQLServer будет интерпретировать ИЛИ по-другому, если бы были разрывы строк ... Я никогда не понял бы смысл WHERE-предложения, такого как A AND B AND C AND D AND E AND F AND G ИЛИ A AND B И C И D AND Е И Ж И Н   -  person MDB    schedule 24.02.2016


Ответы (2)


Я не знаю об относительных преимуществах DNF/CNF в этой ситуации или даже о том, как заставить оптимизатор работать таким образом.

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

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

person Clockwork-Muse    schedule 25.07.2011

Внезапно я задаюсь вопросом об индексации G или H. Если G индексируется, а H нет ... возможно, дизъюнктив имел бы больше смысла.

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

Кроме того, вот некоторые исследования, к которым вы можете получить доступ, если хотите погрузиться в них: Материал исследования: http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=842265&abstractAccess.=no&userType=inst

person Chains    schedule 25.07.2011
comment
В этом случае G и H фактически относятся к одному и тому же столбцу; G — это столбец, подобный «word1%», а H — это столбец, подобный «word2%», поэтому я не могу использовать IN или BETWEEN. Но мне нравится эта мысль. - person Jodaka; 25.07.2011