2009-04-27 77 views
0

我有一個複雜的SQL where子句,由於需求更改而變得更復雜。有四種基本的案例集合,每種都有其他因素的不同組合。它更具可讀性(在我看來)將四種情況作爲where子句的獨立分支,並在每個分支中重複冗餘標準。但我不知道數據庫引擎如何優化。複雜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 

除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的答案。

回答

2

在一個RDBMS世界我不會爲冗餘而煩惱,效率在這裏更重要。

在你的情況,我會用A的爲最佳狀態UNION所有的四個查詢,像這樣:

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年,但在所有主要是RDBMSUNIONOR更有效率。

看到這篇文章在我的博客的方式,以silimar問題Oracle

,也這篇文章的UNION有效使用。在UNION比較與ORMySQL

我認爲這些方法會爲Sybase工作也很好。

您還需要建立在你的條件下使用列的索引從UNION的利益

更新:

由於條件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 

進行任何進一步的判斷,這將是好得多看到查詢本身,真的。

+0

好的建議。標準G使用子查詢會使UNION方法效率更低(因爲理論上它會發生在兩個SELECT中),還是數據庫引擎會優化這些類型的事情? – 2009-04-27 16:44:19

0

我會重構它。最終,重複的邏輯會讓你陷入困境。第二個例子可能需要幾秒鐘才能理解,但是在大範圍的事情中,更容易看到發生了什麼,因爲您可以快速查看整個where子句並開始確定會影響什麼。

2

如果我在M $ SQL Server上攻擊這個問題,我會按照我想要的方式編寫它,並查看查詢執行計劃。如果它(a)運行緩慢並且(b)執行計劃不好,那麼我會重構和記錄。不確定在Sybase中查看優化器如何執行查詢的機制。

+0

感謝您的帖子。在Sybase中,您可以在運行查詢之前運行SET SHOWPLAN ON,它會向您顯示詳細信息(儘管是基於文本的格式,而不是SQL Server的圖形表示) – 2009-04-27 16:20:04