与WHERE结合-拆分WHERE子句

时间:2018-10-07 08:57:26

标签: sql query-optimization

我解决了查询at this link

  

您能否返回未命名为“ Willow Rosenberg”且不在“如何与母亲见面”中的角色和电视节目列表?

具有以下代码:

SELECT ch.name,sh.name
FROM character ch 
  INNER JOIN character_tv_show chat
                 ON ch.id = chat.character_id
                      INNER JOIN tv_show sh
                                     ON chat.tv_show_id=sh.id
                                     WHERE ch.name != "Willow Rosenberg" AND sh.name !="How I Met Your Mother"
;

但是,我的第一次尝试是:

SELECT ch.name,sh.name
FROM character ch 
WHERE ch.name != "Willow Rosenberg" /*This here*/
  INNER JOIN character_tv_show chat
                 ON ch.id = chat.character_id
                      INNER JOIN tv_show sh
                                     ON chat.tv_show_id=sh.id
                                     WHERE sh.name !="How I Met Your Mother"
;

因为我认为以这种方式在执行联接之前只对表character进行了过滤,因此,它的计算量减少了。

这有意义吗?

在连接多个表时,是否有一种方法可以“拆分” WHERE子句?

4 个答案:

答案 0 :(得分:1)

您可以使用子查询

SELECT ch.name,sh.name
  FROM (
        SELECT ch.name
        FROM character ch 
        WHERE ch.name != "Willow Rosenberg") ch
  INNER JOIN character_tv_show chat
             ON ch.id = chat.character_id
  INNER JOIN tv_show sh
             ON chat.tv_show_id=sh.id
  WHERE sh.name !="How I Met Your Mother"

但是我认为这没有道理。子查询将使临时表。 第一次查询将由数据库服务器优化,并且可能仅从字符表中选择需要的行

答案 1 :(得分:1)

JOIN视为两个表的叉积,并使用ON子句中指定的条件对其进行过滤。然后将您的WHERE子句应用于结果集,而不应用于参与联接的单个表。

enter image description here

如果仅要将WHERE应用于连接的表之一,则必须使用子查询。然后,该子查询的过滤结果将被视为普通表,并再次使用JOIN real 表联接。

如果您这样做是为了提高性能,请记住,对于正确索引的表,与子查询相比,标准JOIN上的联接几乎总是更快。您会发现,除极少数情况外,使用JOIN的查询将比使用子查询的查询快几个数量级。

答案 2 :(得分:1)

JOINWHERE子句不一定按照您编写它们的顺序执行。通常,查询优化器会重新安排事情以使其尽可能高效(或至少认为最有效的事情),因此添加第二个WHERE子句与添加另一个{{1 }}条件(这就是为什么不允许这样做的原因)。

您的想法还不错,但这不是数据库的实际工作方式。

答案 3 :(得分:1)

一个SELECT只能有1个WHERE子句。
它是在JOIN之后的。

但是您可以在加入的子查询中包含其他WHERE子句。

有时,您添加到WHERE子句中的条件可以移至JOIN的ON。

例如,以下查询将返回相同的结果

SELECT *
FROM Table1 AS t1
JOIN Table2 AS t2 ON t2.ID = t1.table2ID
WHERE t1.Col1 = 'foo'
AND t2.Col1 = 'bar'

SELECT *
FROM 
(
   SELECT * 
   FROM Table1 
   WHERE Col1 = 'foo'
) AS t1
JOIN Table2 AS t2 ON t2.ID = t1.table2ID
WHERE t2.Col1 = 'bar'

SELECT *
FROM Table1 AS t1
JOIN Table2 AS t2 ON (t2.ID = t1.table2ID AND t2.Col1 = 'bar')
WHERE t1.Col1 = 'foo'