哪个查询更合适?

时间:2012-08-22 05:02:15

标签: sql-server sql-server-2008 tsql

   TABLE T1                    TABLE T2
   +----+------------+         +----+------------+
   | Id |   Name     |         | Id |  Some_Data |
   +----+------------+         +----+------------+
   |    |            |         |    |            |

查询1:

SELECT * FROM T1 JOIN T2 ON T1.Id=T2.Id WHERE T1.Id=1001

QUERY2:

SELECT * FROM T1 JOIN T2 ON T1.Id=T2.Id WHERE T2.Id=1001

如果T2有1000万行,其中只有100行具有Id = 1001,那么上述查询中哪一个更适合使用?或者无关紧要,因为SQL Server足够聪明,知道该做什么最好?

感谢。

7 个答案:

答案 0 :(得分:2)

如果两个ID列都有索引,则会使用一些散列连接变体,并且表的顺序无关紧要

如果Index不可用,那么在左侧表中使用where子句只是为了使NL连接更有效。(我有一种感觉,基于参与表MSSQLSERVER的统计信息将是智能交换自己的订单)

答案 1 :(得分:1)

怎么样:

SELECT * FROM T1 JOIN T2 ON (T1.Id=T2.Id AND T2.Id=1001)

他们说放T2.Id=1001会过滤,然后选择行,但将其放入Where T2.Id=1001会先选择条件T1.Id=T2.Id的所有行,然后应用T2.Id=1001

答案 2 :(得分:1)

根据我的说法,Query2更合适。

SELECT * FROM T1 JOIN T2 ON T1.Id=T2.Id WHERE T2.Id=1001

它会限制返回的行数,因此效率更高,您仍然可以检查the docs

答案 3 :(得分:1)

我猜你需要在两个id列上都有非聚集索引,然后使用上面的任何一个查询来快速获得结果。否则,我认为您无法在上述任何查询中更快地处理查询。在这种情况下,索引必须是。

答案 4 :(得分:1)

我认为这里的问题是连接 - 有数百万行 - 总是先到,然后才会出现where子句。 在您的表上尝试此操作,并在消息选项卡中查看时间戳:

declare @t1 table (id int, name nvarchar(100));
declare @t2 table (id int, name nvarchar(100));

insert into @t1 (id, name) values (1, 'a')
insert into @t1 (id, name) values (2, 'b')
insert into @t1 (id, name) values (3, 'c')
insert into @t1 (id, name) values (4, 'd')
insert into @t1 (id, name) values (5, 'e')

insert into @t2 (id, name) values (5, 'e')
insert into @t2 (id, name) values (5, 'f')
insert into @t2 (id, name) values (5, 'g')
insert into @t2 (id, name) values (5, 'h')
insert into @t2 (id, name) values (5, 'i')
insert into @t2 (id, name) values (6, 'j')
insert into @t2 (id, name) values (7, 'k')
insert into @t2 (id, name) values (8, 'l')

print getdate()
-- this is your select statement
select * from @t1 t1 inner join @t2 t2 on t1.id = t2.id where t1.id = 5;
print getdate()
-- this is your select statement
select * from @t1 t1 inner join @t2 t2 on t1.id = t2.id where t2.id = 5;
print getdate()
-- this is done with a WITH to do the filtering beforehand
-- of course, indices will affect the performance a lot
with w2 (id, name) as (select * from @t2 where id = 5) 
select * from w2 inner join @t1 t1 on w2.id = t1.id
print getdate()

当然,忽略我的示例数据并像使用WITH子句那样使用表。

答案 5 :(得分:1)

首先过滤然后加入

怎么样?
SELECT * FROM T1 
JOIN (SELECT Id FROM T2 WHERE T2.Id=1001) T2
ON T1.Id=T2.Id 

答案 6 :(得分:0)

首先,这是我面临的一个真实问题,数据库来自第三方软件产品,我只读取访问权限以生成一些报告。

在所有非常有帮助的回答者中,我认为没有直截了当的回答。我从帖子中得出结论:首先确保对键控列进行索引,然后让SQL Server负责优化。

感谢所有人。