Postgresql

JOIN 或 WHERE 子句中的平等?效率和風格

  • November 4, 2014

在下面的兩個查詢中,哪個對 postgresql 最有效?並且在可讀性等方面具有更好的風格。

不同之處在於語句的位置doctor.type != 'surgeon'

在 WHERE 子句中:

SELECT practice.name, doctor.name 
FROM doctor 
JOIN practice ON (doctor_code = code) 
WHERE doctor.name LIKE '%son' 
AND (doctor.type != 'surgeon');

或在 JOIN 子句中:

SELECT practice.name, doctor.name
FROM doctor
JOIN practice ON (doctor_code = code AND doctor.type != 'surgeon')
WHERE doctor.name LIKE '%son';

說到風格,你可以在幾個地方改進:

除了克雷格已經寫過的內容。

  • 有一個條件只涉及子句中的doctorJOIN,而另一個條件在子句中是不一致的WHERE。保持一致,兩者都或沒有。最好將它們放在WHERE子句中,而連結兩個表的條件進入JOIN子句 - 可能使用USING. 見下文。
  • 對某些列 ( doctor.name, doctor.type) 進行表限定也是不一致的,但對其他列 ( ) 則不是code。在較大的查詢中,最好始終對所有列進行表限定以避免命名衝突。
  • “名字”不是個好名字。你應該很少使用它。使用不會在每個表中重複的有意義的標識符。一旦你加入了幾個表(這是你在 SQL 中一直做的事情),你最終會得到多個名為“name”的列,並且必須處理列別名才能使用它。“id”或“code”同樣是不好的選擇。

使用如下建議的描述性標識符。

  • 使用doctor.codeand是一種反模式practice.doctor_code。一些不太聰明的 ORM 習慣於使用它——這並不是一個好主意。除了“程式碼”是一個錯誤的標識符之外,對具有相同數據的列使用*相同的名稱是一種很好的做法。*兩個地方都用。或者更好的是:,因為列中的內容可能是“標識符”而不是“程式碼”(錯誤術語)。這樣的命名約定還允許在連接中使用方便的構造doctor_codedoctor_idUSING
  • 使用 SQL 標準**<>**而不是等效的!=.
  • 使用表別名來縮短程式碼並保持可讀性。

所有東西放在一起,它可能看起來像這樣:

SELECT p.practice, d.name  -- for a person, "name" is halfway sensible
FROM   doctor d
JOIN   practice p USING (doctor_id)
WHERE  d.name LIKE '%son'
AND    d.doc_type <> 'surgeon';

這些括號都不是必需的。

內部連接的效率是相同的(只要您在 下join_collapse_limit)。對於大於 PostgreSQL 的連接重新排序限制的連接列表,ON謂詞中的額外項可能會更快。

專注於風格。它在邏輯上是連接一個表到另一個表的條件的一部分嗎?把它放在ON謂詞中。是無關的嗎?把它放在WHERE子句中。

引用自:https://dba.stackexchange.com/questions/81717