如何让MS-Access为我的查询选择不同/正确的执行计划

Mat*_*agé 5 ms-access sql-optimization sql-execution-plan

我有一个相对简单的查询问题和执行计划Access选择它.

查询是这种形式

SELECT somethings
FROM A INNER JOIN (B INNER JOIN (C INNER JOIN D ON ...) ON ...) ON ...
WHERE A.primaryKey= 1 AND D.d = 2;
Run Code Online (Sandbox Code Playgroud)

C和D的行数相对较少.A和B有几千行.

该查询返回2行(不确定这是否相关)真的很慢.它运行17秒.如果我删除AND D.d = 2where子句的一部分,查询现在返回4行并立即运行.

所以我的理解是JET引擎可以立即运行查询而不在Dd上使用过滤器,然后立即执行所述过滤器(仅过滤4行).因此,使用D.d = 2过滤器运行查询不应该太长.

我试图创建一个没有过滤器的子查询,并将其包含在另一个只过滤结果的查询中,但它仍然很慢.我的猜测是JET引擎足够聪明以"扁平化"子查询,因此结果是相同的.

因为我无法按照我的意愿运行查询,所以我使用了JETSHOWPLAN,以便Access输出它的执行计划.这是我发现的:

对于快速查询(没有D.d = 2),查询计划的第一步是A.primaryKey = 1在A表上应用过滤器.这导致超过30000的数据集为1行.然后,连接似乎是使用索引从A到D执行,数据集永远不会超过4行.

慢查询似乎以逆转顺序执行.首先连接D和C然后D.d = 2进行测试.之后,执行从C到A的连接.通过这种方式,需要从D到C,从C到B以及从B到A连接的数据要大得多.当执行所有JOIN并且执行之前A.primaryKey=1,数据集将具有120K行.

有没有办法在Access上强制执行正确的查询计划?

我希望我很清楚.如果我发布查询计划,请告诉我.我没有,因为它们很大.

提前致谢,

熔点

Mat*_*agé 2

我最终通过混合各种东西来让它工作,直到查询规划器同意我的意见。我在子查询中隔离了“A.primaryKey= 1”,以确保它在 A 连接到 B 之前执行。它是这样的:

SELECT ... 
FROM (SELECT ... FROM A WHERE a.primaryKey=1) AS qryA
   INNER JOIN B ...
WHERE D.d = 2;
Run Code Online (Sandbox Code Playgroud)