我对相对简单的查询和 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;
C 和 D 的行数相对较少。A 和 B 有几千行。
返回 2 行的查询(不确定这是否相关)真的很慢。它在 17 秒内运行。如果我删除AND D.d = 2
where 子句的一部分,查询现在返回 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 都被执行并且 beforeA.primaryKey=1
被执行时,数据集将有 120K 行。
有没有办法可以在 Access 上强制执行正确的查询计划?
我希望我很清楚。让我知道是否应该发布查询计划。我没有,因为它们很大。
提前致谢,
mp