ACCESS 2000:通过添加“WHERE”子句来查询“链”太慢

时间:2013-04-09 12:13:29

标签: sql performance ms-access

PREMISE

我必须修改一个非常旧的Access 2000数据库。 我有两张桌子:

  

产品表:

     
      
  • pID as Text - 这是关键字段(是的,是Text,我无能为力)
  •   
  • pLevel as Integer - 这是产品级别:0 =已完成,1到7 =子产品
  •   
  • pDescription as text - 只是一个描述
  •   
     

P-Association 表:

     
      
  • pIDParent as Text
  •   
  • pIDChild as Text
  •   

此表的作用是(子)产品与其他子产品之间的关联。 “规则”是pIDChild级别必须高于pIDParent级别。

然后有一个表单显示给定pID的所有子节点。这是基于查询的“链”:

这是查询q-pAssociation0,它查看所选产品并返回子项:

SELECT DISTINCTROW [t-Associations].pIDParent, [t-Associations].pIDChild, [t-Products].pLevel AS pParentLevel, [t-Products].pLevel AS pChildLevel FROM [t-Products] INNER JOIN [t-Associations] ON [t-Products].pID = [t-Associations].pIDChild
WHERE ((([t-Associations].pIDParent)=[Forms]![fTreeProdotti]![txtProdID]));

然后有7个查询(q-pAssociation1~q-pAssociation7),每个查询都在前一个查询。 这是q-pAssociation1:

SELECT DISTINCTROW [q-pAssociation0].pIDChild AS pIDParent, [t-Associations].pIDChild, [q-pAssociation0].pChildLevel AS pParentLevel, [t-Products].pLevel AS pChildLevel FROM [q-pAssociation0] INNER JOIN ([t-Products] INNER JOIN [t-Associations] ON [t-Products].pID = [t-Associations].pIDChild) ON [q-pAssociation0].pIDChild = [t-Associations].pIDParent;

最后,有一个GROUP查询将所有以前的查询分组,并且表单基于该查询。

问题 我有查询与水平=父级别只返回童车的所有修改此+ 1(因此,如果父母具有2儿童水平“向下”或多种它不必被返回。

所以,我在每个查询中添加了一个条件:

SELECT DISTINCTROW [q-pAssociation0].pIDChild AS pIDParent, [t-Associations].pIDChild, [q-pAssociation0].pChildLevel AS pParentLevel, [t-Products].pLevel AS pChildLevel
FROM [q-pAssociation0] INNER JOIN ([t-Products] INNER JOIN [t-Associations] ON [t-Products].pID = [t-Associations].pIDChild) ON [q-pAssociation0].pIDChild = [t-Associations].pIDParent
WHERE ((([t-Products].pLevel)=[q-pAssociation0]![pParentLevel]+1));

但是现在q-pAssociation7需要10分钟才能返回大约15条记录,而没有“WHERE”条件它几乎可以立即返回大约25条记录。

如果没有这么慢的查询,我怎样才能获得只有一个级别的产品?

1 个答案:

答案 0 :(得分:1)

如果您创建的查询隔离了一个级别的所有关联,那么它可能会有所帮助......

SELECT a.pIDParent, a.pIDChild, tP.pLevel AS pParentLevel, tC.pLevel AS pChildLevel
FROM ([t-Associations] AS a INNER JOIN [t-Products] AS tP ON a.pIDParent = tP.pID) 
    INNER JOIN [t-Products] AS tC ON a.pIDChild = tC.pID
WHERE (((tC.pLevel)=[tP].[pLevel]+1));

...将其保存为[q-one_level_down],然后在查询中使用它,这样您就不必保持(明确地)返回Products表以获取级别。

如果您这样做,那么您的[q-pAssociation0]查询将变为......

SELECT [q-one_level_down].pIDParent, [q-one_level_down].pIDChild, 
    [q-one_level_down].pParentLevel, [q-one_level_down].pChildLevel
FROM [q-one_level_down]
WHERE ((([q-one_level_down].pIDParent)=[Forms]![fTreeProdotti]![txtProdID]));

...(我相信)你的[q-pAssociation1]查询变为

SELECT [q-one_level_down].pIDParent, [q-one_level_down].pIDChild, 
    [q-one_level_down].pParentLevel, [q-one_level_down].pChildLevel
FROM [q-pAssociation0__NEW_] INNER JOIN [q-one_level_down] 
    ON ([q-pAssociation0__NEW_].pChildLevel = [q-one_level_down].pParentLevel) 
        AND ([q-pAssociation0__NEW_].pIDChild = [q-one_level_down].pIDParent);

如果这种方法为您提供了所需的结果,但仍然发现它太慢,那么下一个改进将是使用Append查询将[q-one_level_down]的结果保存在已将所有四列索引的本地表中,然后使用它。 (在这种情况下,你可能想为它命名[lt-one_level_down] - “lt”代表“本地表” - 以避免混淆。)