我有两个具有相同名称,类型和索引键列的表.其中一个具有唯一的聚簇索引,另一个具有非唯一的索引.
测试设置
DROP TABLE IF EXISTS #left; DROP TABLE IF EXISTS #right; CREATE TABLE #left ( a char(4) NOT NULL,b char(2) NOT NULL,c varchar(13) NOT NULL,d bit NOT NULL,e char(4) NOT NULL,f char(25) NULL,g char(25) NOT NULL,h char(25) NULL --- and a few other columns ); CREATE UNIQUE CLUSTERED INDEX IX ON #left (a,b,c,d,e,f,g,h) UPDATE STATISTICS #left WITH ROWCOUNT=63800000,PAGECOUNT=186000; CREATE TABLE #right ( a char(4) NOT NULL,h char(25) NULL --- and a few other columns ); CREATE CLUSTERED INDEX IX ON #right (a,h) UPDATE STATISTICS #right WITH ROWCOUNT=55700000,PAGECOUNT=128000;
复制品
当我在他们的集群键上加入这两个表时,我希望有一对多的MERGE连接,如下所示:
SELECT * FROM #left AS l LEFT JOIN #right AS r ON l.a=r.a AND l.b=r.b AND l.c=r.c AND l.d=r.d AND l.e=r.e AND l.f=r.f AND l.g=r.g AND l.h=r.h WHERE l.a='2018';
这是我想要的查询计划:
(别介意警告,它们与虚假统计数据有关.)
但是,如果我在连接中更改列的顺序,如下所示:
SELECT * FROM #left AS l LEFT JOIN #right AS r ON l.c=r.c AND -- used to be third l.a=r.a AND -- used to be first l.b=r.b AND -- used to be second l.d=r.d AND l.e=r.e AND l.f=r.f AND l.g=r.g AND l.h=r.h WHERE l.a='2018';
… 有时候是这样的:
Sort运算符似乎根据声明的连接顺序对流进行排序,即c,a,h,这会向我的查询计划添加阻塞操作.
我看过的东西
>我已经尝试将列更改为NOT NULL,结果相同.
>原始表是使用ANSI_PADDING OFF创建的,但使用ANSI_PADDING ON创建它不会影响此计划.
>我尝试了INNER JOIN而不是LEFT JOIN,没有变化.
>我在2014 SP2 Enterprise上发现了它,在2017 Developer(当前CU)上创建了一个repro.
>删除前导索引列上的WHERE子句会生成好的计划,但它会影响结果.. 原文链接:https://www.f2er.com/mssql/79493.html