我几乎确信这是MS Access内连接中的一个漏洞。这真是太可怕了,因为它是我应该用于app dev的东西。不,这不是内部联接的预期行为 - 我已经让3个不同的人(自己计算)来确认。
因此,查询正在实施"最大的n组"通过最大查询获得最高优先级,然后将该结果用作过滤回原始文件以检索所需的非组字段。 (附带问题 - 是"第一个"在一个有序的表上真的足够稳定,可以通过一次传递来完成吗?)所说的非分组字段是第三个表上一个键的一部分。
此查询的特定配置会丢弃我数据的特定子集中的一半记录(我已放大)。如果我将第三个表的连接切换到" max filter"表而不是基表,突然它正常工作。 (有问题的字段显示在所有3个表格中,并且已经从" base"加到" max过滤器"已经。)
我的小组确实超过了11个字段。并且交换已连接字段的哪个副本确实会改变我的查询执行计划。但是没有一种类型的版本似乎不起作用。我不知道内部联接和分组如何能够插入错误的查询计划,但我似乎已经设法了。
我知道没有实际的sql代码[现已发布],但它分布在多个查询中,可能还需要我得到的数据。有没有办法上传一个实际的.mdb文件,以便人们可以使用产生错误的副本?我刚刚发帖,但我还没有看到一个带有.mdb的帖子,所以我不确定如何最好地获得这个帖子所需的详细信息。
或者,如果有人知道可能发生的事情(未分类的联接有10个字段限制?)可能导致这种情况,我将在周一进一步查看。我以前在C中孤立的记忆没有泄漏,所以我想我知道一两件事,但是这个只是简单的迷惑 - 我真的不想以为我可能不得不在vba中实现内部联接,因为我不能信任Access(并且无法获得更好的工具)。
[进一步编辑:我是这个过程的唯一设计师,因此,一旦它不是别人的代码 - 我的问题本身就是我自己的问题。]
2013-12-30编辑 - 添加SQL墙 SQL之墙:
错误查询仅返回测试子集上16个结果中的8个:
SELECT
Allocations.Allocation_ID,
SLJ.Exp_Sign,
SLJ.Proj_ID,
SLJ.Doc_ID,
Allocations.Expense_Catagory,
SLJ.Prod_ID,
SLJ.OrigP_Type,
SLJ.OrigP,
SLJ.Class_ID,
Sum(SLJ.Total*[share]) AS Resposible_Doc_Count,
MP.MaxOfPriority,
SLJ.Priority,
MP.OrigP,
MP.Exp_Sign,
IIf(MP.exp_sign=SLJ.exp_sign,"true","false") AS What
FROM
(MP INNER JOIN SLJ
ON (MP.Exp_Sign = SLJ.Exp_Sign)
AND (MP.E_Delivery = SLJ.E_Delivery)
AND (MP.Expense_Type = SLJ.Expense_Type)
AND (MP.Proj_ID = SLJ.Proj_ID)
AND (MP.Doc_ID = SLJ.Doc_ID)
AND (MP.Doc_Typ_ID = SLJ.Doc_Typ_ID)
AND (MP.Prod_ID = SLJ.Prod_ID)
AND (MP.OrigP_Type = SLJ.OrigP_Type)
AND (MP.Class_ID = SLJ.Class_ID)
AND (MP.OrigP = SLJ.OrigP)
AND (MP.MaxOfPriority = SLJ.Priority)
AND (MP.Invested = SLJ.Invested))
INNER JOIN Allocations
ON (SLJ.Alloc_ID = Allocations.Allocation_ID)
AND (SLJ.Invested = Allocations.Invested)
AND (SLJ.E_Delivery = Allocations.E_Delivery)
AND (SLJ.Expense_Type = Allocations.Expense_Type)
GROUP BY
Allocations.Allocation_ID,
SLJ.Exp_Sign,
SLJ.Proj_ID,
SLJ.Doc_ID,
Allocations.Expense_Catagory,
SLJ.Prod_ID,
SLJ.OrigP_Type,
SLJ.OrigP,
SLJ.Class_ID,
MP.MaxOfPriority,
SLJ.Priority,
MP.OrigP,
MP.Exp_Sign,
IIf(MP.exp_sign=SLJ.exp_sign,"true","false");
良好的查询返回所有16个结果:
SELECT Allocations.Allocation_ID,
SLJ.Exp_Sign,
SLJ.Proj_ID,
SLJ.Doc_ID,
Allocations.Expense_Catagory,
SLJ.Prod_ID,
SLJ.OrigP_Type,
SLJ.OrigP,
SLJ.Class_ID,
Sum(SLJ.Total*[share]) AS Resposible_Doc_Count,
MP.MaxOfPriority,
SLJ.Priority,
MP.OrigP,
MP.Exp_Sign,
IIf(MP.exp_sign=SLJ.exp_sign,"true","false") AS What
FROM
(MP INNER JOIN SLJ
ON (MP.Invested = SLJ.Invested)
AND (MP.MaxOfPriority = SLJ.Priority)
AND (MP.OrigP = SLJ.OrigP)
AND (MP.Class_ID = SLJ.Class_ID)
AND (MP.OrigP_Type = SLJ.OrigP_Type)
AND (MP.Prod_ID = SLJ.Prod_ID)
AND (MP.Doc_Typ_ID = SLJ.Doc_Typ_ID)
AND (MP.Doc_ID = SLJ.Doc_ID)
AND (MP.Proj_ID = SLJ.Proj_ID)
AND (MP.Expense_Type = SLJ.Expense_Type)
AND (MP.E_Delivery = SLJ.E_Delivery)
AND (MP.Exp_Sign = SLJ.Exp_Sign))
INNER JOIN Allocations
ON (Allocations.Expense_Type = MP.Expense_Type)
AND (Allocations.E_Delivery = MP.E_Delivery)
AND (Allocations.Invested = MP.Invested)
AND (SLJ.Alloc_ID = Allocations.Allocation_ID)
GROUP BY Allocations.Allocation_ID,
SLJ.Exp_Sign,
SLJ.Proj_ID,
SLJ.Doc_ID,
Allocations.Expense_Catagory,
SLJ.Prod_ID,
SLJ.OrigP_Type,
SLJ.OrigP,
SLJ.Class_ID,
MP.MaxOfPriority,
SLJ.Priority,
MP.OrigP,
MP.Exp_Sign,
IIf(MP.exp_sign=SLJ.exp_sign,"true","false");
查询设计师的差异 - 加入"分配"针对两个存在的三个字段的MP而不是SLJ ... allocation_id仅在SLJ上。 (分别为Max_Priority和Stats_Loose_Join。)
底层查询/表格:
MP:
SELECT
Max(SLJ.Priority) AS MaxOfPriority,
SLJ.Exp_Sign,
SLJ.Invested,
SLJ.E_Delivery,
SLJ.Expense_Type,
SLJ.Proj_ID,
SLJ.Doc_ID,
SLJ.Doc_Typ_ID,
SLJ.Prod_ID,
SLJ.OrigP_Type,
SLJ.OrigP,
SLJ.Class_ID
FROM SLJ
GROUP BY
SLJ.Exp_Sign,
SLJ.Invested,
SLJ.E_Delivery,
SLJ.Expense_Type,
SLJ.Proj_ID,
SLJ.Doc_ID,
SLJ.Doc_Typ_ID,
SLJ.Prod_ID,
SLJ.OrigP_Type,
SLJ.OrigP,
SLJ.Class_ID;
SLJ - 过滤(通过哪里)到4个记录的测试集:
SELECT
KS.Alloc_ID,
KS.Priority,
KS.Exp_Sign,
StatsT.*
FROM
KS,
StatsT
WHERE
(
(
(KS.Proj_ID) Is Null
Or (KS.Proj_ID)=[StatsT].[proj_id]
)
AND (
(KS.Doc_ID) Is Null
Or (KS.Doc_ID)=[StatsT].[doc_id]
)
AND (
(KS.Doc_Typ_ID) Is Null
Or (KS.Doc_Typ_ID)=[StatsT].[doc_typ_id]
)
AND (
(KS.Prod_ID) Is Null
Or (KS.Prod_ID)=[StatsT].[prod_id]
)
AND (
(KS.OrigP_Type) Is Null
Or (KS.OrigP_Type)=[StatsT].[OrigP_Type]
)
AND (
(KS.OrigP) Is Null
Or (KS.OrigP)=[StatsT].[OrigP]
)
AND (
(KS.Class_ID) Is Null
Or (KS.Class_ID)=[StatsT].[class_id]
)
AND ((StatsT.Doc_ID)=10437)
AND ((StatsT.Prod_ID)=104));
SLJ结果:
Alloc_ID Priority Exp_Sign Invested E_Delivery Expense_Type Proj_ID Doc_ID Doc_Typ_ID Prod_ID OrigP_Type OrigP Class_ID Total
1 10 Gross Y N Inforce 2013_199 10437 5 104 Fund_Doc 40 -1 1
1 10 Gross Y N Inforce 2013_199 10437 5 104 Fund_Doc 43 -1 1
-1 10 Reimb Y N Inforce 2013_199 10437 5 104 Fund_Doc 40 -1 1
-1 10 Reimb Y N Inforce 2013_199 10437 5 104 Fund_Doc 43 -1 1
StatsT:
SELECT
E2_In__Bound_Stats__Long.Invested,
E2_In__Bound_Stats__Long.E_Delivery,
E2_In__Bound_Stats__Long.Expense_Type,
E2_In__Bound_Stats__Long.Proj_ID,
E2_In__Bound_Stats__Long.Doc_ID,
E2_In__Docs_List__Doc.Doc_Typ_ID,
E2_In__Bound_Stats__Long.Prod_ID,
E2_In__Bound_Stats__Long.OrigP_Type,
E2_In__Bound_Stats__Long.OrigP,
E2_In__Bound_Stats__Long.Class_ID,
E2_In__Bound_Stats__Long.Total
FROM
E2_In__Bound_Stats__Long
INNER JOIN
E2_In__Docs_List__Doc
ON
E2_In__Bound_Stats__Long.Doc_ID = E2_In__Docs_List__Doc.Doc_ID;
KS表(Kitchen_Sink) - 119行 - 空条目阻止主键:
Alloc_ID Priority Exp_Sign Proj_ID Doc_ID Doc_Typ_ID Prod_ID OrigP_Type OrigP Class_ID
Docs_List表 - 12465行 - 主键是Doc_ID:
Doc_ID Doc_Typ_ID
Bound_Stats表 - 1289行(或100k左右),只有4个在SLJ上存活过滤 - 主键最初未设置,应该是除Total之外的所有内容,设置没有删除bug:
Invested E_Delivery Expense_Type Proj_ID Doc_ID Prod_ID OrigP_Type OrigP Class_ID Total
访问查询计划:
糟糕的计划:
--- Matrix_Math_AAA ---
查询输入
Table 'KS'
Table 'E2_In__Bound_Stats__Long'
Table 'E2_In__Docs_List__Doc'
Using index 'PrimaryKey'
Having Indexes:
PrimaryKey 12465 entries, 22 pages, 12465 values
which has 1 column, fixed, unique, primary-key, no-nulls
Doc_Type_ID1 12465 entries, 15 pages, 14 values
which has 1 column, fixed
Doc_ID1 12465 entries, 22 pages, 12465 values
which has 1 column, fixed
Table 'KS'
Table 'E2_In__Bound_Stats__Long'
Table 'E2_In__Docs_List__Doc'
Using index 'PrimaryKey'
Having Indexes:
PrimaryKey 12465 entries, 22 pages, 12465 values
which has 1 column, fixed, unique, primary-key, no-nulls
Doc_Type_ID1 12465 entries, 15 pages, 14 values
which has 1 column, fixed
Doc_ID1 12465 entries, 22 pages, 12465 values
which has 1 column, fixed
Table 'Allocations'
结束对查询的输入
好计划:
--- Matrix_Math_AAA_Good ---
查询输入
Table 'KS'
Table 'E2_In__Bound_Stats__Long'
Table 'E2_In__Docs_List__Doc'
Using index 'PrimaryKey'
Having Indexes:
PrimaryKey 12465 entries, 22 pages, 12465 values
which has 1 column, fixed, unique, primary-key, no-nulls
Doc_Type_ID1 12465 entries, 15 pages, 14 values
which has 1 column, fixed
Doc_ID1 12465 entries, 22 pages, 12465 values
which has 1 column, fixed
Table 'KS'
Table 'E2_In__Bound_Stats__Long'
Table 'E2_In__Docs_List__Doc'
Using index 'PrimaryKey'
Having Indexes:
PrimaryKey 12465 entries, 22 pages, 12465 values
which has 1 column, fixed, unique, primary-key, no-nulls
Doc_Type_ID1 12465 entries, 15 pages, 14 values
which has 1 column, fixed
Doc_ID1 12465 entries, 22 pages, 12465 values
which has 1 column, fixed
Table 'Allocations'
Using index 'PrimaryKey'
Having Indexes:
PrimaryKey 312 entries, 4 pages, 312 values
which has 5 columns, fixed, unique, primary-key, no-nulls
Allocation_ID 312 entries, 1 page, 6 values
which has 1 column, fixed
结束对查询的输入
结束2013-12-30编辑
答案 0 :(得分:0)
建议的答案 - 任何人都可以证实这是有道理的吗?
bound_stats表有一个11字段主键。 “松散”连接为SLJ提供了最多12个字段的概念键。 MP是一个获得最大游击(最大组数)的组具有11个字段键,但也必须以优先级(最大n)连接回SLJ。因此,有一个12字段连接,其中第11个字段碰巧有一些distingushing数据(我认为错误)。
在错误查询计划的情况下,步骤11是:
11)使用临时索引
我认为这个临时索引受到10个字段的访问限制。因此,前10个之后的字段产生不正确的结果。好的查询计划使用排序,虽然可能较慢,但可能绕过索引的10字段限制(或者只是幸运)。
解决方案:重新设计系统以避免键大于长度8 可能的替代方案:使用显式排序+“第一”访问功能来实现单通道解决方案到最大n组。取决于“排序依据”避免10场限制 - 我不知道这是否属实。
那么 - 我确实找到了解决方案,还是因为不重要的事情而分心?如果访问在连接上抛出错误而不是错误地执行错误,那肯定会很好。