我在MS Access 2010中使用下面的查询有明显的执行问题(直到超时)。表TempTableAnalysis包含10'000-15'000个记录。我已收到此论坛的输入,以便在前10个查询中使用临时表(MS Access 2010 SQL Top N query by group performance issue)
任何人都可以解释如何在子查询中实现临时表以及如何加入它?我无法让它发挥作用。
高度赞赏任何其他改善表现的建议。
这是我的问题:
SELECT
t2.Loc,
t2.ABCByPick,
t2.Planner,
t2.DmdUnit,
ROUND(t2.MASE,2) AS MASE,
ROUND(t2.AFAR,2) AS AFAR
FROM TempTableAnalysis AS t2
WHERE t2.MASE IN (
SELECT TOP 10 t1.MASE
FROM TempTableAnalysis AS t1
WHERE t1.ABCByPick = t2.ABCByPick
ORDER BY t1.MASE DESC
)
ORDER BY
t2.ABCByPick,
t2.MASE DESC;
答案 0 :(得分:2)
根据您发布的SQL查询,您可以使用一些选项来优化和加快性能。
SELECT
t2.Loc,
t2.ABCByPick,
t2.Planner,
t2.DmdUnit,
ROUND(t2.MASE,2) AS MASE,
ROUND(t2.AFAR,2) AS AFAR
FROM TempTableAnalysis AS t2
...
这是TempTableAnalysis
是千万条记录子查询的第一部分。如果你想从使用这个“Temp”表中获得更多的性能,不要将它用作动态查询(即,每次打开查询时按需计算),尝试构建一个推动查询的宏输出到静态表:
将子查询数据附加到静态表:
创建QUERY
对象并将其类型更改为DELETE
。设计它以删除“临时”表对象的内容。如果您更喜欢使用SQL,那么命令将如下所示:
DELETE My_Table.*
FROM My_Table;
创建QUERY
对象并将其类型更改为APPEND
。设计它以查询由此OP的SQL语句定义的查询中的所有字段。同样,此任务的SQL版本具有以下语法:
INSERT INTO StaticAnalysisTable ( ID, Loc, Item, AvgOfScaledError )
SELECT t1.ID, t1.Loc, t1.Item, t1.AvgOfScaledError
FROM TempTableAnalysis as t1;
下一步是自动化这个静态表的填充,它是可选的。但这很简单,并且会让你不太可能忘记“刷新”并访问静态表,而它有陈旧的数据......导致结果不准确。
通过两个步骤创建一个宏。每个步骤都有以下定义:OPEN QUERY
。当系统提示您打开查询时,按以下顺序引用您在前两个步骤中创建的对象(重要):( 1)DELETE Query: (your delete query name)
然后(2)APPEND Query: (your append query name)
。
SQL查询评论和建议
发布的SQL查询的以下部分可以使用一些帮助:
...
WHERE t2.MASE IN (
SELECT TOP 10 t1.MASE
FROM TempTableAnalysis AS t1
WHERE t1.ABCByPick = t2.ABCByPick
ORDER BY t1.MASE DESC
)
ORDER BY
t2.ABCByPick,
t2.MASE DESC;
在子查询中存在生成TOP-10数据的连接,以及将这些结果与补充MASE
表数据相关联的最外层查询。如果TempTableAnalysis.MASE
代表键值,则无需这样做。
ORDER BY
在最内层查询中是不必要的,这看起来不像其中一种情况。从大型数据集中订购记录也是一个浪费的CPU和内存接收器。
编辑:就像一个反点参数一样,TOP N查询旁边使用的
ORDER BY
子句实际上有一个目的,但我仍然不清楚是否有必要。为了完善讨论,另一个SO线程讨论了How to Select Top 10 in an Access Query。
WHERE t2.MASE IN (...
使用非常大的列表集操作可能会遇到性能阻塞。在Oracle数据库服务器上,我发现与其他开发人员一样,列表内查询运算符中的离散元素数量存在限制。该值为数千......可能会根据服务器和数据库资源进一步限制。
考虑使用SQL JOIN
运算符。定义TABLE
对象的位置也可以使用SQL定义的查询填充,其别名称为INLINE VIEWS
。由于您使用的是ACCESS,如果内联视图无法直接使用,只需定义另一个ACCESS QUERY
对象并在最终查询中引用它,就好像它是一个表...
可能重写原始查询的结尾部分:
SELECT
t2.Loc,
t2.ABCByPick,
t2.Planner,
...
FROM TempTableAnalysis AS t2,
(SELECT TOP 10 t1.MASE, t1.ABCByPick
FROM TempTableAnalysis AS t1) AS ttop
WHERE t2.MASE = ttop.MASE
AND t2.ABCByPick = ttop.ABCByPick
ORDER BY
t2.ABCByPick,
t2.MASE DESC;
您肯定需要完成这些建议并验证输出数据的准确性。这代表了捕获一些“低悬的水果”(简单项目)的方法,您可以采取这些方法来加速查询和报告操作。
结论和结束评论
作为其他读者的背景,数据库对象TempTableAnalysis
不是静态表。这是在另一个SO帖子中提出的子查询的结果,请求Access TOP N Query的帮助。查询来自多个表,大小接近10,000个记录(每个?)。
提示: Access ALSO中的查询结果具有潜在的表格式行为。您可以将输出推送到表以进行连接(如上所述),或者只是加入查询对象本身(但要小心,尤其是当您“链接”多个查询操作时......)
此解决方案的策略是:
最大限度地减少通过这张超大桌子的一个或多个实例的次数。
预处理和索引优化任何在分析期间“静态”的数据。
审核并查看用于获取最终结果的SQL代码。
绝对关注Access MACROS。与识别数据集中的静态数据相结合,您可以卸载复杂背景分析查询的处理,以便在查看和查询最终结果时改善用户体验。祝你好运!