2012-07-09 76 views
3

我還在學習SQL。我以兩種不同的方式完成了類似的查詢,並想知道哪個更好,爲什麼。哪些SQL查詢更好,爲什麼?

UPDATE R 
    SET R.something = 1 
    FROM Table1 R 
    JOIN Table2 U 
    ON R.value1 = U.value2 
    WHERE 
     U.value3 BETWEEN 1 AND 5 

UPDATE R 
    SET R.something = 1 
    WHERE R.value1 IN 
    (SELECT U.value2 
    FROM U 
    WHERE 
     U.value3 BETWEEN 1 AND 5 
    ) 
+3

你檢查過查詢執行計劃嗎? – Taryn 2012-07-09 15:40:12

+0

太棒了!不知道執行計劃。從我可以看出,他們看起來完全平等。這似乎並不正確。 – John 2012-07-09 15:43:43

+3

優化器優化:)如果統計信息/索引類似,則語法非常不同的兩個SQL語句看起來與數據庫引擎類似。 – 2012-07-09 15:45:49

回答

0

更好的將是與查詢JOIN,因爲它會比次選得更快。

+0

嗯OP說執行計劃是相同的,所以它似乎不可能 – 2012-07-09 17:36:01

0

這取決於數據庫和數據庫版本 搜索上或加入是否是更好的(快)返回不同的 結果(快或加入更快),這取決於甚至對SQL語句從數據庫 上 - 它甚至可以根據 數據庫版本進行更改。測試多個數據大小和不同平臺總是一個好主意!

(查詢#2是最容易閱讀,但可能會或可能不會慢)

2

你的問題沒有一個單一的答案。 SQL是一種描述性語言,而不是過程語言。這取決於數據庫引擎將更加高效。另外,指數可能會對績效產生重大影響。

你的兩個查詢,順便說一句,是不等價的。當「U」中有多個值時,第一個可以返回多行。帶有「IN」的版本確實隱含了「DISTINCT」。要解決這個問題,你需要添加一個特定的「DISTINCT」。

UPDATE R 
    SET R.something = 1 
    FROM Table1 R 
     JOIN (select distinct value2 
       from Table2 U 
       WHERE U.value3 BETWEEN 1 AND 5 
      ) u 
     ON R.value1 = U.value2 

而且,雖然我個人很喜歡「FROM」中的更新語句,並非所有的數據庫都支持它。帶有「IN」的版本可以在更廣泛的數據庫引擎中兼容。

1

這一切都取決於你計劃在表中使用(甲骨文,SQL Server和等),其版本,有時對數據量的數據庫上。但通常你應該更喜歡JOIN,因爲它們對於大多數優化器來說更容易,而對於空值則更少。

+0

我想不出一個例子,其中空值的因素到* JOIN和IN *你能提供一個嗎? – 2012-07-09 17:38:56

+0

「子查詢或表達式返回的任何空值與使用IN或NOT IN返回UNKNOWN的test_expression進行比較。將空值與IN或NOT IN一起使用可能會產生意外的結果。」請參閱http://msdn.microsoft.com/en-us/library/ms177682.aspx – 2012-07-09 19:59:43

+0

這是一個很好的引用,但這不是一個示例,也不解釋JOIN將如何不同。 [這是一個例子](http://sqlfiddle.com/#!3/6b35e/2),其中JOIN和IN的行爲是相同的。你可以嘗試創建一個它不是?否則,我仍然會因爲你的意思而感到困惑, – 2012-07-09 20:38:40

0

這可能取決於你所使用的引擎,但我相信MS SQL Server將既優化到相同的查詢計劃。

如果發動機沒有我建議它是在這種情況下遜色。

1

第一個查詢更好。

關係數據庫,無論您使用的實際DBMS的,正好是建連接數據以這種方式與where子句過濾。這是他們的麪包和黃油。在第二個查詢中,您正在使用子查詢來收集其他數據。這非常酷,而且關係數據庫也可以通過這種方式來解決問題。但是,對於子查詢,並且在這種特定情況下,您最終會得到兩個查詢,一個用於獲取U數據,然後使用子查詢中的數據設置R數據,然後執行外部查詢。

這裏是有點棘手,但。在你的查詢中,你的子查詢完全引用一個單獨的表。所以它仍然會很快。該子查詢僅包含U數據。您將得到2個查詢 - 獲取U數據,然後使用U數據更新R數據。但是如果你寫了一個類似的查詢,其中子查詢引用了來自R的數據,那麼你不會得到兩個單獨的查詢。你最終會對R中的所有數據進行全表掃描,這會比較慢。

編輯更完整:正如其他人所說,很多都歸結爲您正在使用的DBMS以及它的最佳功能。而當第一次學習SQL(我絕不是專家)時,其中一個障礙就是意識到有很多方法可以做同樣的事情,獲得​​相同的結果,然後通常最終得到相同的結果。因此找到「正確」的方式通常是徒勞的,因爲沒有明確的「正確」方式。我不僅寫正確性和速度,而且寫可維護性 - 我發現子查詢可能比必要的更難。如果我可以避免它們,我會盡量避免使用它們(只要替代方法不是遊標或其他東西:-D)。