2012-07-09 74 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)。