哪个SQL查询更快?在Join条件上进行筛选还是使用Where子句?

12 浏览
0 Comments

哪个SQL查询更快?在Join条件上进行筛选还是使用Where子句?

比较这两个查询。将过滤器放在连接条件还是在WHERE子句中更快?我一直觉得将过滤器放在连接条件中更快,因为它能在最早的时刻减少结果集,但我不确定。

我将进行一些测试,但我也想听听哪种更容易阅读的意见。

查询1:

选择所有

从表A a

内连接表XRef x

在a.ID = x.TableAID上

内连接表B b

在x.TableBID = b.ID上

WHERE a.ID = 1 /* <-- 过滤器在这里? */

查询2:

选择所有

从表A a

内连接表XRef x

在a.ID = x.TableAID上

并且a.ID = 1 /* <-- 还是在这里过滤器? */

内连接表B b

在x.TableBID = b.ID上

编辑:

我进行了一些测试,结果显示实际上非常接近,但WHERE子句稍微更快!=)

我完全同意在WHERE子句上应用过滤器更有意义,我只是对性能影响感到好奇。

经过时间的比较WHERE条件:143016毫秒

经过时间的比较JOIN条件:143256毫秒

测试:

SET NOCOUNT ON;

DECLARE @num INT,

@iter INT

SELECT @num = 1000, -- TableA和TableB中的记录数,交叉表通过从A到B进行CROSS JOIN填充

@iter = 1000 -- 要执行的选择迭代次数

DECLARE @a TABLE (

id INT

)

DECLARE @b TABLE (

id INT

)

DECLARE @x TABLE (

aid INT,

bid INT

)

DECLARE @num_curr INT

SELECT @num_curr = 1

WHILE (@num_curr <= @num)

BEGIN

INSERT @a (id) SELECT @num_curr

INSERT @b (id) SELECT @num_curr

SELECT @num_curr = @num_curr + 1

END

INSERT @x (aid, bid)

SELECT a.id,

b.id

FROM @a a

CROSS JOIN @b b

/*

测试

*/

DECLARE @begin_where DATETIME,

@end_where DATETIME,

@count_where INT,

@begin_join DATETIME,

@end_join DATETIME,

@count_join INT,

@curr INT,

@aid INT

DECLARE @temp TABLE (

curr INT,

aid INT,

bid INT

)

DELETE FROM @temp

SELECT @curr = 0,

@aid = 50

SELECT @begin_where = CURRENT_TIMESTAMP

WHILE (@curr < @iter)

BEGIN

INSERT @temp (curr, aid, bid)

SELECT @curr,

aid,

bid

FROM @a a

INNER JOIN @x x

ON a.id = x.aid

INNER JOIN @b b

ON x.bid = b.id

WHERE a.id = @aid

SELECT @curr = @curr + 1

END

SELECT @end_where = CURRENT_TIMESTAMP

SELECT @count_where = COUNT(1) FROM @temp

DELETE FROM @temp

SELECT @curr = 0

SELECT @begin_join = CURRENT_TIMESTAMP

WHILE (@curr < @iter)

BEGIN

INSERT @temp (curr, aid, bid)

SELECT @curr,

aid,

bid

FROM @a a

INNER JOIN @x x

ON a.id = x.aid

AND a.id = @aid

INNER JOIN @b b

ON x.bid = b.id

SELECT @curr = @curr + 1

END

SELECT @end_join = CURRENT_TIMESTAMP

SELECT @count_join = COUNT(1) FROM @temp

DELETE FROM @temp

SELECT @count_where AS count_where,

@count_join AS count_join,

DATEDIFF(millisecond, @begin_where, @end_where) AS elapsed_where,

DATEDIFF(millisecond, @begin_join, @end_join) AS elapsed_join

0
0 Comments

哪个SQL查询更快?基于连接条件的过滤还是基于WHERE子句的过滤?

当涉及到性能时,它们是相同的(并且产生相同的执行计划)。

从逻辑上讲,如果你用LEFT JOIN替换INNER JOIN,应该选择仍然有意义的操作。

在你的情况下,可以这样实现:

SELECT *

FROM TableA a

LEFT JOIN TableXRef x

ON x.TableAID = a.ID

AND a.ID = 1

LEFT JOIN TableB b

ON x.TableBID = b.ID

或者这样实现:

SELECT *

FROM TableA a

LEFT JOIN TableXRef x

ON x.TableAID = a.ID

LEFT JOIN TableB b

ON b.id = x.TableBID

WHERE a.id = 1

前一个查询将只返回与a.id = 1匹配的实际结果,因此后一种语法(带有WHERE子句)在逻辑上更一致。

当我绘制集合时,我明白了为什么第二种情况更一致。在前一个查询中,约束条件a.id = 1只适用于交集部分,而不适用于排除交集的左侧部分。

在第一个示例中,可能存在a.id != 1的行,而第二个示例只有a.id = 1的行。

你的语言不清楚。"从逻辑上讲,你应该选择仍然有意义的操作..."和"在逻辑上更一致"没有意义。你能重新表达一下吗?

0
0 Comments

在SQL查询中,有两种常用的筛选数据的方法,即使用JOIN/ON操作和使用WHERE子句。JOIN/ON操作用于连接表,而WHERE子句用于筛选结果。这两种方法可以根据具体情况进行不同的使用,但是我个人认为总是感觉有些不对劲。只有在性能成为问题时,才需要考虑这样的“优化”。但是这样的回答似乎并没有解答问题。

这个问题的出现原因是有人想知道在SQL查询中,使用JOIN条件进行筛选还是使用WHERE子句进行筛选,哪种方法更快。下面将介绍一些关于这个的问题和解决方法。

有些人认为在大多数情况下,使用WHERE子句进行筛选会更快。因为通过使用WHERE子句,可以在连接之前先筛选出满足条件的数据,减少了需要连接的数据量。这样可以减少连接操作的时间和资源消耗。而使用JOIN/ON操作进行筛选,则需要先连接表,然后再筛选数据,可能会增加查询的时间和资源消耗。

然而,也有一些人认为使用JOIN条件进行筛选会更快。因为使用JOIN条件可以利用数据库的索引,提高查询的效率。而使用WHERE子句进行筛选,则可能无法充分利用索引,导致查询效率较低。

为了解决这个问题,可以使用不同的方法进行测试和比较。可以编写两个不同的SQL查询语句,一个使用JOIN/ON操作进行筛选,另一个使用WHERE子句进行筛选。然后通过执行这两个查询语句,并比较它们的执行时间和资源消耗来判断哪个方法更快。

下面是一个示例代码,用于比较使用JOIN/ON操作和使用WHERE子句进行筛选的查询效率:

-- 使用JOIN/ON操作进行筛选

SELECT *

FROM table1

JOIN table2 ON table1.id = table2.id

WHERE table1.column1 = 'value';

-- 使用WHERE子句进行筛选

SELECT *

FROM table1

JOIN table2 ON table1.id = table2.id

WHERE table2.column1 = 'value';

通过执行以上两个查询语句,并比较它们的执行时间和资源消耗,可以得出哪个方法更快的结论。

总之,在选择使用JOIN/ON操作还是WHERE子句进行筛选时,需要根据具体情况进行考虑。可以通过测试和比较来确定哪种方法更适合当前的查询需求。同时,还可以考虑其他的优化方法,如创建合适的索引、优化查询语句等,来提高查询的性能。

0
0 Comments

在内连接中,将条件放在哪里并不重要。SQL编译器会将两者都转化为执行计划,其中过滤发生在连接之下(即,就像过滤表达式出现在连接条件中一样)。

而对于外连接来说,过滤条件的位置会改变查询的语义。

所以在内连接中,它首先计算过滤条件,然后将过滤条件的输出与另一个表进行连接,或者首先连接两个表,然后应用过滤条件?

Rusanu-您能详细说明一下外连接的语义如何改变吗?根据过滤条件的位置,我得到了不同的结果,但无法理解为什么。

在外连接中,如果JOIN条件不匹配,所有与连接表相关的列都会得到NULL值。过滤条件不会满足NULL值,并消除行,将外连接实际上转变为内连接。

根据您的评论,我实现了所需的优化。我的更改是将"WHERE x.TableAID = a.ID or x.TableAID is null"更改为"ON x.TableAID = a.ID"。改变了外连接中过滤条件的位置后,编译器知道先过滤再连接,而不是先连接再过滤。它还能够使用该列上的索引,因为它不需要匹配NULL值。查询响应时间从61秒变为2秒。

0