【问题标题】:Join two big tables on multiple columns in Access在 Access 中的多个列上加入两个大表
【发布时间】:2018-07-02 11:41:33
【问题描述】:

我有两张桌子:

  1. 大约有 300,000 行的交易和以下字段:

    • 交易 ID
    • 客户 ID
    • 类型
  2. 大约 10,000 行的价格和以下字段:

    • 客户 ID
    • 类型
    • 价格

我尝试使用 4 个字段加入它们:ClientID, Q, Y, Type,但我一直收到 2GB 错误,说结果表太大。问题是结果应该是 300,000 行,所以我的猜测是 Access 以某种愚蠢的方式执行此操作,首先创建笛卡尔积并引发错误。有趣的是,如果我只使用 ClientID 加入它就可以正常工作并提供数百万行。

谁能帮我找到正确的出路?或许我只需要了解一下join是如何在幕后执行的,但到目前为止我还没有发现任何有意义的东西。

我考虑添加 hash 列,该列将在两个表中连接 4 列并使用它来连接,但它是如此丑陋的解决方案,我只是畏缩。

我现在的SQL是这样的

SELECT TransactionID, Price 
FROM Transactions 
INNER JOIN Prices
   ON Transactions.ClientID = Prices.ClientID 
  AND Transactions.Q = Prices.Q 
  AND Transactions.Y = Prices.Y 
  AND Transactions.Type = Prices.Type

【问题讨论】:

  • 只有这两个表的数据库的当前大小是多少?
  • 你在加入之前压缩了数据库吗?
  • 你有正确的 clientId 索引吗?
  • @PatrickHonorez 我没有,但最终目标是动态生成这些表,所以我不认为这是一个解决方案。

标签: sql ms-access join


【解决方案1】:

尝试使用派生表来强制执行不同的查询:

SELECT TransactionID, Price FROM 
(SELECT TransactionID, Price, Transactions.Q as TransQ, Prices.Q as PricesQ,
Transactions.Y as TransY, Prices.Y as PricesY, Transactions.Type as
TransType, Prices.Type as PricesType
FROM Transactions INNER JOIN Prices
ON Transactions.ClientID = Prices.ClientID) AS Step1
WHERE TransQ = PricesQ AND TransY = PricesY
AND TransType = PricesType

【讨论】:

  • 这个想法很简洁,但显然 Access 想要比我更聪明,并且仍然会抛出错误。但是,您和@Parfait 的想法导致了我要使用的解决方法。我将仅将连接结果放在临时数据库中的 ClientID 上,然后仅选择匹配 Q、Y 和 Type 的那些。
  • @brainac ...很好奇,将数据表 .accdb 文件与查询应用程序 .accdb 文件链接起来的结果是什么,您在后者的文件中对前者的链接表运行原始查询?
  • @Parfait 不确定我是否理解您的问题,但最终我将大约 1100 万条记录的结果表放入临时数据库中,仅在查询中使用 [;database=],然后我删除了不匹配的行Qs、Ys 和类型。剩余的 300k 行很容易与用于存储结果的表连接。花了大约 3 个小时和 350MB,但由于这是一次锻炼,我对此很好。下次我只做一个月,而不是两年的数据,所以会快得多。
【解决方案2】:

根据Access 2016 specifications,大小限制定义为:

2 GB,减去系统对象所需的空间。

处理此查询的虚拟表可能是问题所在。要在查询窗口中显示SELECT 语句结果,需要将数据临时存储在系统对象中。如果原始文件已经很大,那么在 JOIN 查询中使用相同表的连接(即副本)会更大。

按照上述相同规范的建议,考虑将 Prices 迁移到不同的 .accdb/.mdb 文件并使用链接表(访问访问)进行查询。而且,如果您保留相同的表名,则无需更改原始查询!或者,在外部查询,如下所示。这样,您就可以将处理临时表大小与存储大小分开以适应 2GB 配额。

SELECT t.TransactionID, Price 
FROM Transactions t
INNER JOIN [C:\Path\To\Other\Database.accdb].[Prices] p
   ON t.ClientID = p.ClientID 
  AND t.Q = p.Q 
  AND t.Y = p.Y 
  AND t.Type = p.Type

即便如此,将两个表存储在不同的文件中,并使用不同的无数据 Access 应用程序来运行查询。事实上,这是 Access 开发推荐的理想拆分架构,其中包含表的存储(后端)与包含查询/表单/报告/宏/模块的应用程序(前端)分开。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    相关资源
    最近更新 更多