为什么使用 VBA 函数的 SQL 查询运行速度如此之慢?

编程入门 行业动态 更新时间:2024-10-08 13:33:46
本文介绍了为什么使用 VBA 函数的 SQL 查询运行速度如此之慢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我继承了一个在很多地方执行以下类型查询的应用:

I've inherited an app that does the following kind query in a lot of places:

select foo.f1, foo.f2, foo.f3 from foo where foo.f4 = getFooF4()

getFooF4 看起来像这样

getFooF4 looks like this

Public Function getFooF4() Dim dbCurrent As Database Dim rstBar As Recordset Set dbCurrent = CurrentDb Set rstBar = dbCurrent.OpenRecordset("Bar", _ dbOpenDynaset, _ dbSeeChanges) getFooF4 = rstBar![myF4] ''yes this appears broken... Bar only contains one row :-/ rstBar.close Set rstBar = Nothing dbCurrent.close Set dbCurrent = Nothing End Function '' Note: in my experimentation getFooF4 only runs once during the '' execution of the query.

这最终运行得很慢.如果我使用常量从查询中删除 getFooF4():

This ends up running fairly slow. If I remove getFooF4() from the query with a constant:

select foo.f1, foo.f2, foo.f3 from foo where foo.f4 = 123456

或参数:

select foo.f1, foo.f2, foo.f3 from foo where foo.f4 = [myFooF4]

或加入:

select foo.f1, foo.f2, foo.f3 from foo INNER JOIN bar ON bar.myF4 = foo.f4

它运行得更快.

为什么?

规格:应用在 MS Access 2003 中编写并运行,后端数据库为 SQL Server 2008.

Specs: App written and running in MS Access 2003, back-end database is SQL Server 2008.

推荐答案

提高效率的两件事(尽管只有其中一项适用于这样的特定情况):

Two things to improve efficiency (though only one or the other will ever apply to a particular case like this):

  • 为你的函数定义一个返回类型,即 Public Function getFooF4() 应该是 Public Function getFooF4() As Long(或任何适当的数据type 是.如果没有明确的数据类型,它会返回一个变体.实际上,从来没有一个 VBA 函数应该缺少返回类型声明——如果它返回一个变体(这是完全合理的,特别是当你需要返回时在某些情况下为空),用 As Variant 定义它.当它是其他数据类型时,明确定义它.

  • define a return type for your function, i.e., Public Function getFooF4() should be Public Function getFooF4() As Long (or whatever the appropriate data type is. Without an explicit data type, it's returning a variant. In reality, there is never a VBA function that should ever lack a return type declaration -- if it's returning a variant (which is perfectly reasonable, particularly when you need to return Null in some cases), define it with As Variant. When it's some other data type, explicitly define it.

    在您的 SQL 中声明一个参数,以便查询优化器可以在其查询计划的计算中使用该信息.当您的 WHERE 子句使用函数来提供条件时,这不适用,但如果您使用对控件上的字段的引用,则应替换为:

    declare a parameter in your SQL so that the query optimizer can use that information in its calculation of the query plan. That doesn't apply when your WHERE clause is using a function to supply the criterion, but if you were using a reference to a field on a control, you'd replace this:

    .

    select foo.f1, foo.f2, foo.f3 from foo where foo.f4 = Forms!MyForm!MyControl

    ...这样:

    PARAMETERS [Forms]![MyForm]![MyControl] Long; select foo.f1, foo.f2, foo.f3 from foo where foo.f4 = Forms!MyForm!MyControl

    现在,在这两种情况下,由于函数/参数在 WHERE 子句中,它只需要解析一次,所以即使函数效率低下(就像这里的情况一样,它初始化了一个数据库变量和打开记录集),实际上不会有太大区别.

    Now, in either of these cases, since the function/parameter is in the WHERE clause, it needs to be resolved only once, so even if the function is inefficient (as is the case here, with it initializing a database variable and opening a recordset), it won't actually make much difference.

    另一件需要考虑的事情是用一个简单的 DLookup() 替换该函数,该函数正是为此目的而设计的.或者,由于该值来自一个表,您应该能够将它加入到您的单行表中:

    Another thing to consider is replacing the function with a simple DLookup(), which is designed for exactly this purpose. Alternatively, since the value is coming from a table, you should be able to JOIN it to your one-row table:

    select foo.f1, foo.f2, foo.f3 from foo INNER JOIN Bar ON foo.f4 = Bar.MyF4

    这将被查询优化器最大程度地优化,因为它根本没有未知数——查询优化器将知道它需要知道的关于数据类型和表统计信息的一切,并且可以选择最有效的检索方法.

    This would be maximally optimizable by the query optimizer since there are no unknowns in it at all -- the query optimizer will know everything it needs to know about data types and table stats and can pick the most efficient retrieval method possible.

  • 更多推荐

    为什么使用 VBA 函数的 SQL 查询运行速度如此之慢?

    本文发布于:2023-11-27 18:07:36,感谢您对本站的认可!
    本文链接:https://www.elefans.com/category/jswz/34/1639046.html
    版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
    本文标签:运行速度   函数   VBA   SQL

    发布评论

    评论列表 (有 0 条评论)
    草根站长

    >www.elefans.com

    编程频道|电子爱好者 - 技术资讯及电子产品介绍!