所以我在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)。
从我在网上发现的一点,似乎DNF允许SQL单独运行连接词,并在最后联合它们。
然而,对于这样的事情,有这么多重复的条件,DNF真的比CNF有优势吗?如果没有,我如何强制优化器按原样接受条件?如果是这样,我应该在应用程序代码中以CNF形式编写查询,因为它更短更简洁,还是以DNF形式编写查询,因为它可以节省优化器的时间?
我不知道DNF/CNF在这种情况下的相对优势,甚至不知道如何以这种方式强制优化器。
一般来说,你不想强迫优化器接受你的"感知","当前"优化,而不是它将生成的优化(也有例外,但这些通常是罕见的)。这在很大程度上与"最佳"优化可能随着时间的推移而改变这一事实有关,这是其他操作(如添加索引)的副作用。如果你强迫优化器采用一个特定的优化,你就把它锁定在那个路径上,即使一个新的优化可能会表现得更好。
考虑到这一点,您应该以最易于阅读和维护(CNF)的形式编写查询,并在必要时让优化器对其进行更改——这就是SQL作为声明性语言的全部意义所在,以便优化器在必要时进行处理。
我想知道G或H上的索引,如果G被索引,但H没有…也许一个析取词会更有意义。
无论如何,您可以自己运行性能分析器来查看性能的净差异。
除此之外,如果你想深入研究,这里有一些研究可能可以访问:研究资料:http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=842265&abstractAccess=no&userType=inst