0

我有一个复杂的 SQL where 子句,由于需求更改而变得更加复杂。有四组基本案例,每组都有其他因素的不同组合。将四个案例作为 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

除 A4 之外的所有 A 都采用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 的答案。

4

3 回答 3

2

如果我在 M$ SQL Server 上解决这个问题,我会按照我想要的方式编写它并查看查询执行计划。如果它 (a) 运行缓慢并且 (b) 有一个糟糕的执行计划,那么我会重构并记录。不确定 Sybase 中用于查看优化器如何执行查询的机制是什么。

于 2009-04-27T16:17:23.463 回答
2

在一个RDBMS我不会为冗余而烦恼的世界里,效率在这里更为重要。

在您的情况下,我会将UNION所有四个查询都使用A's 作为顶级条件,如下所示:

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
…

多年来我没有研究Sybase7,但在所有专业RDBMS的 ' UNIONs 都比 's 更有效OR

请参阅我的博客中的这篇文章,了解解决类似问题的方法Oracle

还有这篇文章用于比较UNIONORin MySQL

  • 选择朋友:与in中UNION的一个相比的效率ORMySQL

我认为这些方法也适用Sybase

您还需要在条件中使用的列上创建索引以受益UNION

更新:

由于 conditionG是一个子查询,它可能需要 aHASH 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

为了做出任何进一步的判断,真正地查看查询本身会好得多。

于 2009-04-27T16:35:07.993 回答
0

我会重构它。最终,重复的逻辑会让你遇到问题。第二个示例可能需要几秒钟的时间才能理解,但在大范围内更容易看到发生了什么,因为您可以快速查看整个 where 子句并开始确定影响什么。

于 2009-04-27T16:14:23.097 回答