[英]Why is arel adding unnecessary parentheses to 'a and b or c and d or ..' query
這是一個示例(沒有意義,但是很好地舉例說明)
t = DimensionType.arel_table
q = t.where(
t[:label].eq('a').and(t[:label].eq('b'))
.or(t[:label].eq('c').and(t[:label].eq('d')))
.or(t[:label].eq('e').and(t[:label].eq('f')))
.or(t[:label].eq('g').and(t[:label].eq('e')))
).to_sql
puts q
這是輸出:
SELECT FROM "dimension_types" WHERE ((("dimension_types"."label" = 'a' AND "dimension_types"."label" = 'b' OR "dimension_types"."label" = 'c' AND "dimension_types"."label" = 'd') OR "dimension_types"."label" = 'e' AND "dimension_types"."label" = 'f') OR "dimension_types"."label" = 'g' AND "dimension_types"."label" = 'e')
括號起什么作用? 如果沒有,如何避免出現? 他們將where部分放在一種可能影響查詢優化的層次結構中。
編輯:意圖是要有這樣的查詢(在人為的元語言中):
(a and b) or (b and c) or (d and e)
沒有括號就一樣,因為and
優先於or
a and b or b and c or d and e
如果我錯了,請糾正我。
括號會改變布爾運算符的優先順序,並起着將邏輯組合在一起的作用。 沒有它們,含義將完全不同(基於從左到右的讀取順序和AND / OR的相對優先級)。
簡單來說,如果沒有括號,則AND總是在OR之前求值。
這些不相等
A and B or C
A and (B or C)
第一個計算A and
B,然后計算or
s,第二個計算s or
B和C之前and
與A。
括號可確保按特定順序執行特定的邏輯分組。
在您的特定情況下,您希望所有AND在OR之前進行評估,但是LINQ通過在幕后導航邏輯“樹”將邏輯轉換為SQL,並且您無法控制該過程。 這樣做是為了確保結果符合您的預期,這通常意味着多余的括號。
由於大多數處理時間是從驅動器中獲取數據,而不是評估SQL中的括號,因此您不必擔心。 您可以假設任何優化都將在更廣泛的水平上起作用,並且盡管有括號也可以起作用(實際上,它甚至可以更有效地起作用):)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.