繁体   English   中英

在 SQL 服务器中,如何使 sql 在两个连接的表上使用“或”子句使用正确的索引

[英]In SQL Server, how do I make sql using "or" clauses over two connected tables use the correct indexes

我有两个表TableATableB ,它们由AID相关。 AIDTableA中的主键和TableB中的外键。

以下 SQL 用于 select 从TableB连接到TableA的任何内容,其中ADescBDesc类似于某个值。

SQL1:

SELECT *
FROM TableB
INNER JOIN TableA ON TableA.AID = TableB.AID
WHERE ADesc LIKE 'A0A4D1%' OR BDesc = 'A0A4D1%'
  • 表 A 在AID ( TableA_PK ) 上有一个聚集索引
  • 表 A 在ADesc ( TableA_I1 ) 上有一个非聚集索引
  • 表 B 在BID ( TableB_PK ) 上有一个聚集索引
  • 表 B 在BDesc ( TableB_I1 ) 上有一个非聚集索引

如果我将上面的 SQL 分成两条语句(或一条语句与 SQL2 中的 UNION 连接),SQL 服务器将真正有效地利用TableA_I1TableB_I1并限制ADescBDesc

SQL2:

SELECT *
FROM TableB
INNER JOIN TableA ON TableA.AID = TableB.AID
WHERE ADesc LIKE 'A0A4D1%'
UNION 
SELECT *
FROM TableB
INNER JOIN TableA ON TableA.AID = TableB.AID
WHERE BDesc = 'A0A4D1%'

但是,SQL1 既不使用TableA_I1也不使用TableB_I1 ,返回速度要慢得多。

我的问题是有没有办法让 SQL 服务器执行 SQL1 但使用与 SQL2 中相同的索引和类似的执行计划?

我正在使用 SQL 服务器 2019。

这似乎是一个奇怪的问题,它引出了下面的问题——你为什么不把它改成 UNION 呢? 第一,我的实际 SQL 要复杂得多,生成的 UNION 会很大,所以我想看看是否可以简化。 第二,我很好奇为什么 SQL 服务器无法解决问题并自行优化。

创建所有表和索引的SQL如下:

CREATE TABLE TableA
(
    AID INT IDENTITY(1,1) NOT NULL, 
    ADesc VARCHAR(50) NOT NULL
)
GO

CREATE NONCLUSTERED INDEX TableA_I1 ON TableA (ADesc ASC)
GO

CREATE UNIQUE CLUSTERED INDEX TableA_PK ON TableA (AID ASC)
GO

CREATE TABLE TableB
( 
    BID INT IDENTITY(1,1) NOT NULL, 
    AID INT NOT NULL, 
    BDesc VARCHAR(50) NOT NULL
)
GO

CREATE NONCLUSTERED INDEX TableB_I1 ON TableB (BDesc ASC)
GO

CREATE UNIQUE CLUSTERED INDEX TableB_PK ON TableB (BID ASC)
GO

然后我将几百万行放入表中以确保有足够的数据 go at!

也许尝试使用以下模式进行试验。 使用带有主键的临时表意味着 SQL 服务器将有准确的统计信息可供使用。

drop table if exists #aid;
create table #aid(aid int primary key);

insert into #aid(aid)
select aid
from TableA
where ADesc like 'A0A4D1%'
union all
select aid
from TableB
where BDesc = 'A0A4D1';

select a.<columns>, b.<columns>
from #aid x
join TableA a on a.aid = x.aid
join TableB b on b.aid = x.aid;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM