MS Access 与带有两个 JOIN 的 MySQL 后端查询会导致查询过多

Nie*_*een 5 mysql sql ms-access odbc

我有 2 个表,Customers并且Countries,像这样:

顾客:

    +----+------+-----+---------------+----------------+
    | ID | Name | ... | OfficeCountry | BillingCountry |
    +----+------+-----+---------------+----------------+
    | 1  | Bill | ... | 1             | 1              |
    | 2  | Joe  | ... | 2             | 1              |
    +----+------+-----+---------------+----------------+
Run Code Online (Sandbox Code Playgroud)

国家:

    +----+-------------+
    | ID | Name        |
    +----+-------------+
    | 1  | USA         |
    | 2  | Netherlands |
    +----+-------------+
Run Code Online (Sandbox Code Playgroud)

(我从表中删除了一些列,Customers只保留了该问题的一些相关列)这两列的目的是计费国家/地区和物理办公地点可能不同。该表中还有更多地址信息,但在本示例中被删除。

JOIN对这两个表进行查询,结果如下:

SELECT
    ID,
    some, 
    fields,
    Countries_1.Name AS OfficeCountryName,
    Countries_2.Name AS BillingCountryName
    
FROM
    Customers
    
    LEFT JOIN
        Countries AS Countries_1
    ON
        Customers.OfficeCountry = Countries_1.ID    
    
    LEFT JOIN
        Countries AS Countries_2
    ON
        Customers.BillingCountry = Countries_2.ID
Run Code Online (Sandbox Code Playgroud)

我们使用的应用程序是带有 MySQL 后端的 MS Access 前端。这是通过 ODBC 完成的。

Customers表包含大约 15,000 条记录。

问题是该应用程序的性能很差。我启用了查询日志,当我将数据(从 DynaSet)加载到表单中时,我可以看到正在执行以下查询:

  • 上面写的查询
  • 一个额外的查询,带有,用旧的遗留语法OUTER JOIN编写{oj ...}
  • 对表进行30.000 次查询(来自 的 COUNT 的 2 倍CustomersCountries。这个确切的查询:(SELECT ID FROM Countries WHERE ID = 2ID = 1,取决于客户)。

最后两个问题让我感到惊讶。

  1. 首先,查询来自哪里OUTER JOIN我从未OUTER JOIN在 Access 中指定过任何内容。另外,旧的遗留{oj ..}语法给我一种感觉有些问题。另外,这个查询是不需要的。我不在 Access 前端使用它的数据,而且我不知道它来自哪里。
  2. 其次,为什么 Access 要查询Countries表中的每条记录?这些数据不是必需的,也没有帮助。它只是SELECT使用它已经知道的 ID(如子句中所示WHERE

正如您可以想象的那样,30,000 个查询极大地降低了性能。

我知道将 15,000 条记录加载到一个表单(带有导航控件等)中并不是一个好的做法,但它是一个非常古老的遗留应用程序,需要重写大量工作。

编辑 我现在看到,对于非常简单的查询,只要有一个目的构建非常干净的形式,它就会生成一些查询:

  1. 选择所有 ID 的查询(对于客户也是如此,并且是 JOIN'ed 表的两倍)
  2. 该查询选择从查询 1 中返回的每个记录的所有必要字段(FOR EVERY TABLE)。所以 SELECT FROM Customers WHERE Id = record_currently_viewed

And*_*dre 4

在链接的 ODBC 表上使用多个 LEFT JOIN 进行访问查询因性能不佳而臭名昭著。如果 MySql ODBC 驱动程序在如此简单的查询上失败,它可能比 Sql Server 驱动程序更糟糕。

怎么修:

1-在这种特殊情况下,实际上根本没有理由使用 LEFT JOIN。没有匹配国家怎么可能有国家FK呢?

您应该修复任何孤立的 FK 并创建具有引用完整性的关系,然后使用 INNER JOIN,问题就会消失。

2- 如果不可能,请将处理移至服务器。创建一个执行连接的视图,在 Access 中链接它,并以它为基础创建表单。

3-如果你根本无法修改后端数据库,你也可以使用PassThrough查询。但这将是只读的。