0
   表 T1 表 T2
   +----+------------+ +----+------------+
   | 身份证 | 姓名 | | 身份证 | 一些数据 |
   +----+------------+ +----+------------+
   | | | | | |

查询1:

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

查询2:

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

如果 T2 有 1000 万行,其中只有 100 行的 Id=1001,那么上述哪个查询更适合使用?或者这并不重要,因为 SQL Server 足够聪明,知道什么是最好的?

谢谢。

4

7 回答 7

2

如果索引在两个 ID 列上都可用,则将使用哈希连接的一些变体,并且表的顺序无关紧要

如果索引不可用,那么在左侧表上有 where 子句是有意义的,只是为了使 NL 连接更有效。(我有一种感觉,基于参与表 MSSQLSERVER 的统计信息将智能地交换顺序本身)

于 2012-08-22T05:11:50.780 回答
1

关于什么:

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

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

于 2012-08-22T05:05:51.303 回答
1

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

于 2012-08-22T07:10:45.687 回答
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 子句一样使用您的表。

于 2012-08-22T07:36:23.330 回答
1

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

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

它将限制返回的行,因此效率更高,您仍然可以查看文档

于 2012-08-22T05:06:11.547 回答
1

先过滤再加入怎么样

SELECT * FROM T1 
JOIN (SELECT Id FROM T2 WHERE T2.Id=1001) T2
ON T1.Id=T2.Id 
于 2012-08-22T07:52:15.747 回答
0

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

从所有非常有帮助的回答者中,我了解到没有直接的答案。我从帖子中得出的结论是:首先确保键控列被索引,然后让 SQL Server 负责优化。

谢谢大家。

于 2012-08-22T13:41:54.377 回答