回答你的问题是不是已经排序够了?- 否。对中的所有列执行比较,SELECT
以便所有列都需要包含在排序中。
我提供了两种可能的解决方案,一种是将所有列添加到索引中,另一种是使用 NOT EXISTS - 请注意,如果 table_a 中有重复行,这可能会返回重复行。
1.) 将这些列包含在索引中,您将在 SQLFiddle 链接查询计划中看到在这种情况下不使用排序。
SQL小提琴
MS SQL Server 2017 架构设置:
create table table_a
(
key_a int identity,
some_field_a int,
some_field2_a varchar(10)
);
WITH Tally (n) AS
(
-- 1000 rows
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(n)
)
insert into table_a
(
some_field_a,
some_field2_a
)
select
n,
'abcd'
from Tally;
create clustered index cix_table_a_key_a on table_a (key_a,some_field_a,
some_field2_a);
create table table_b
(
key_b int identity,
some_field_b int,
some_field2_b varchar(10)
);
WITH Tally (n) AS
(
-- 1000 rows
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(n)
)
insert into table_b
(
some_field_b,
some_field2_b
)
select
n,
'abcd'
from Tally;
create clustered index cix_table_b_key_b on table_b (key_b, some_field_b, some_field2_b);
查询 1:
select
key_a,
some_field_a,
some_field2_a
from table_a
except
select
key_b,
some_field_b,
some_field2_b
from table_b
结果:
2.) 另一种选择是使用NOT EXISTS
代替- 应该注意的是,这些与有效执行 aEXCEPT
并不完全相同。如果将 a 添加到 a,您将在较小的结果表上获得 SORT。EXCEPT
DISTINCT
DISTINCT
NOT EXISTS
请参阅此处的 SQLFIDLLE:
SQL小提琴
MS SQL Server 2017 架构设置:
create table table_a
(
key_a int identity,
some_field_a int,
some_field2_a varchar(10)
);
WITH Tally (n) AS
(
-- 1000 rows
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(n)
)
insert into table_a
(
some_field_a,
some_field2_a
)
select
n,
'abcd'
from Tally;
create clustered index cix_table_a_key_a on table_a (key_a);
create table table_b
(
key_b int identity,
some_field_b int,
some_field2_b varchar(10)
);
WITH Tally (n) AS
(
-- 1000 rows
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(n)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(n)
)
insert into table_b
(
some_field_b,
some_field2_b
)
select
n,
'abcd'
from Tally;
create clustered index cix_table_b_key_b on table_b (key_b);
查询 1:
select
key_a,
some_field_a,
some_field2_a
from table_a
WHERE NOT EXISTS
(
select NULL
from table_b
WHERE
key_b = key_a AND
some_field_b = some_field_a AND
some_field2_b = some_field2_a
)
结果: