Microsoft Access 中 CTE 的替代品
Alternatives to CTEs in Microsoft Access
我每天都使用 MS Access 2010,我想知道是否有 Common Table Expression 的替代方法,因为它在 SQL 服务器,它如何影响性能?
例如,创建子查询更好还是从另一个查询调用查询更好,两者本质上非常相似..
示例:
SELECT A.field1,A.Date
FROM (SELECT * FROM TABLE B WHERE B.Date = Restriction )
或
SELECT A.field1,A.Date
FROM SavedQueryB
保存的查询 B:
SELECT * FROM TABLE B WHERE B.Date = Restriction
我觉得有多个查询更容易调试和管理,但是当数据集非常大时它会影响性能吗?
另外,我看过一些关于通过 VBA 实现查询的视频,但是我还不太习惯那样做。
本质上。 什么是更有效或更好的做法?关于更好的做法有什么建议或建议吗?
我主要通过视频、书籍和一些编程背景自学 (VB.NET)
我不记得在哪里,但那里有关于嵌套或子查询这个话题的讨论。基本上他们都建议保存的查询,然后引用保存的查询。
根据个人经验,嵌套查询极难在以后进行故障排除或修改。此外,如果他们变得太深,我会遇到性能问题。
Allen Browne 列出了一些提示和技巧 here
我经常使用嵌套查询的一个地方是在动作查询的条件中。这样我就没有任何连接并且可以限制一些 "cannot perform this operation" 问题。
最后,使用 VBA 中的查询字符串。我发现构建参数查询然后在 VBA 中为 QueryDef 设置一个变量并添加参数比在 VBA 中构建查询字符串要容易得多。以后更容易进行故障排除和修改。
只是我的两分钱。
对于最简单的查询,例如您问题中的查询,我怀疑您会发现子查询和 "stacked query"(使用另一个保存的查询作为其数据源的查询)方法之间存在显着的性能差异。也许数据库引擎甚至会对两者使用相同的查询计划。 (如果您有兴趣,可以使用 SHOWPLAN 检查查询计划。)
这两个示例的主要性能驱动因素是数据库引擎是否可以使用索引检索来获取满足 WHERE
限制的行。如果 TABLE.Date
没有索引,查询将需要完整的 table 扫描。对于非常大的数据集,这会很糟糕,并且完全扫描对性能的影响应该远远超过子查询和堆叠查询之间的任何差异。
对于复杂的子查询,情况可能会有所不同,因为 Allen Browne explains:
Complex subqueries on tables with many records can be slow to run.
在子查询性能问题的潜在修复中,他建议...
Use stacked queries instead of subqueries. Create a separate saved
query for JET to execute first, and use it as an input "table" for
your main query. This pre-processing is usually (but not always)
faster than a subquery. Likewise, try performing aggregation in one
query, and then create another query that operates on the aggregated
results. This post-processing can be orders of magnitude faster than a
query that tries to do everything in a single query with subqueries.
我认为您最好的答案将来自测试更复杂的现实世界示例。您问题中的查询非常简单,从中得出的结论可能不适用于那些现实世界的查询。
这实际上取决于上下文,因为许多场景将决定最有效的结果,包括数据类型、连接 table、索引等。本质上,对于像发布的 SELECT
statmeents 这样的简单查询,这两个查询是等价的,但是 Jet/ACE 的(MS Access 的底层引擎)查询优化器可能会根据结构需要再次决定不同的计划询问。调用外部查询可能会在执行计划中添加一个步骤,但子查询可以作为独立的 tables 执行,然后链接到主 tables。
回想一下 SQL 的一般操作顺序,它不同于键入的顺序,因为每个步骤都涉及虚拟 table(参见 SQL Server):
FROM clause --VT1
ON clause --VT2
WHERE clause --VT3
GROUP BY clause --VT4
HAVING clause --VT5
SELECT clause --VT6
ORDER BY clause --VT7
可以说是对于存储的查询对象,MS Access 分析并缓存了优化的"best plan"版本。这通常是在 VBA 字符串查询上使用存储查询的论点,后者在执行前未进行优化。更进一步,Access' query 对象类似于其他 RDMS' view 对象(尽管 Jet/ACE 确实有 VIEW
和 PROCEDURE
个对象)。 SQL 世界中的定期讨论涉及您关于效率和最佳实践的问题:views vs subqueries 以及通常的答案 returns "it depends"。所以,根据需要进行试验。
这里的 CTE 被认为是 "inline-views",由 WITH
子句表示(在 JET/ACE 中尚不支持)。 SQL 程序员可以使用 CTE 来提高可读性和可维护性,因为您可以避免在语句主体中多次引用同一语句。总而言之,使用适合您的编码习惯和项目要求的内容,然后根据需要进行调整。
资源
MS Access 2007 查询性能
Tips - 附有关于子查询性能的注释
中级 Microsoft Jet
SQL
- 关于子查询的说明(刚刚了解 ANY/SOME/ALL
)
Microsoft Jet 3.5 性能白色
论文
- 关于查询计划的注释
我每天都使用 MS Access 2010,我想知道是否有 Common Table Expression 的替代方法,因为它在 SQL 服务器,它如何影响性能?
例如,创建子查询更好还是从另一个查询调用查询更好,两者本质上非常相似..
示例:
SELECT A.field1,A.Date
FROM (SELECT * FROM TABLE B WHERE B.Date = Restriction )
或
SELECT A.field1,A.Date
FROM SavedQueryB
保存的查询 B:
SELECT * FROM TABLE B WHERE B.Date = Restriction
我觉得有多个查询更容易调试和管理,但是当数据集非常大时它会影响性能吗?
另外,我看过一些关于通过 VBA 实现查询的视频,但是我还不太习惯那样做。
本质上。 什么是更有效或更好的做法?关于更好的做法有什么建议或建议吗? 我主要通过视频、书籍和一些编程背景自学 (VB.NET)
我不记得在哪里,但那里有关于嵌套或子查询这个话题的讨论。基本上他们都建议保存的查询,然后引用保存的查询。
根据个人经验,嵌套查询极难在以后进行故障排除或修改。此外,如果他们变得太深,我会遇到性能问题。
Allen Browne 列出了一些提示和技巧 here
我经常使用嵌套查询的一个地方是在动作查询的条件中。这样我就没有任何连接并且可以限制一些 "cannot perform this operation" 问题。
最后,使用 VBA 中的查询字符串。我发现构建参数查询然后在 VBA 中为 QueryDef 设置一个变量并添加参数比在 VBA 中构建查询字符串要容易得多。以后更容易进行故障排除和修改。
只是我的两分钱。
对于最简单的查询,例如您问题中的查询,我怀疑您会发现子查询和 "stacked query"(使用另一个保存的查询作为其数据源的查询)方法之间存在显着的性能差异。也许数据库引擎甚至会对两者使用相同的查询计划。 (如果您有兴趣,可以使用 SHOWPLAN 检查查询计划。)
这两个示例的主要性能驱动因素是数据库引擎是否可以使用索引检索来获取满足 WHERE
限制的行。如果 TABLE.Date
没有索引,查询将需要完整的 table 扫描。对于非常大的数据集,这会很糟糕,并且完全扫描对性能的影响应该远远超过子查询和堆叠查询之间的任何差异。
对于复杂的子查询,情况可能会有所不同,因为 Allen Browne explains:
Complex subqueries on tables with many records can be slow to run.
在子查询性能问题的潜在修复中,他建议...
Use stacked queries instead of subqueries. Create a separate saved query for JET to execute first, and use it as an input "table" for your main query. This pre-processing is usually (but not always) faster than a subquery. Likewise, try performing aggregation in one query, and then create another query that operates on the aggregated results. This post-processing can be orders of magnitude faster than a query that tries to do everything in a single query with subqueries.
我认为您最好的答案将来自测试更复杂的现实世界示例。您问题中的查询非常简单,从中得出的结论可能不适用于那些现实世界的查询。
这实际上取决于上下文,因为许多场景将决定最有效的结果,包括数据类型、连接 table、索引等。本质上,对于像发布的 SELECT
statmeents 这样的简单查询,这两个查询是等价的,但是 Jet/ACE 的(MS Access 的底层引擎)查询优化器可能会根据结构需要再次决定不同的计划询问。调用外部查询可能会在执行计划中添加一个步骤,但子查询可以作为独立的 tables 执行,然后链接到主 tables。
回想一下 SQL 的一般操作顺序,它不同于键入的顺序,因为每个步骤都涉及虚拟 table(参见 SQL Server):
FROM clause --VT1
ON clause --VT2
WHERE clause --VT3
GROUP BY clause --VT4
HAVING clause --VT5
SELECT clause --VT6
ORDER BY clause --VT7
可以说是对于存储的查询对象,MS Access 分析并缓存了优化的"best plan"版本。这通常是在 VBA 字符串查询上使用存储查询的论点,后者在执行前未进行优化。更进一步,Access' query 对象类似于其他 RDMS' view 对象(尽管 Jet/ACE 确实有 VIEW
和 PROCEDURE
个对象)。 SQL 世界中的定期讨论涉及您关于效率和最佳实践的问题:views vs subqueries 以及通常的答案 returns "it depends"。所以,根据需要进行试验。
这里的 CTE 被认为是 "inline-views",由 WITH
子句表示(在 JET/ACE 中尚不支持)。 SQL 程序员可以使用 CTE 来提高可读性和可维护性,因为您可以避免在语句主体中多次引用同一语句。总而言之,使用适合您的编码习惯和项目要求的内容,然后根据需要进行调整。
资源
MS Access 2007 查询性能 Tips - 附有关于子查询性能的注释
中级 Microsoft Jet SQL - 关于子查询的说明(刚刚了解
ANY/SOME/ALL
)Microsoft Jet 3.5 性能白色 论文 - 关于查询计划的注释