3

我希望以前没有在这里问过这个问题(我确实在这里搜索过,并在谷歌上搜索过答案,但找不到答案)

问题是:我正在使用 MS Access 2010 从链接表中选择记录(表中有数百万条记录)。如果我直接指定条件(例如日期)(例如 date=#1/1/2013#),查询会立即返回。如果我使用参数(添加日期/时间类型的参数并在提示时提供 2013 年 1 月 1 日的值(或某些不同格式的日期),或引用表单中的控件),则查询需要几分钟才能加载。

如果您对可能导致此问题的原因有任何想法,请告诉我。问这样的问题并可能浪费别人的时间,我确实感到难过...

4

2 回答 2

2

这是一个潜在的答案,我自己不知道,做了一点挖掘。

如果性能很重要,则可能需要更喜欢动态 SQL,即使由于查询的优化方式而适用于参数查询也是如此。通常,Access 会在保存时为新查询创建计划。当查询包含参数时,Access 无法知道该参数可能包含什么值,因此必须做出“正确的猜测”。根据稍后提供的实际值,它可能没问题或很差,从而导致性能欠佳。相反,动态 SQL 回避了这一点,因为“参数”被硬编码到临时字符串中,因此使用该值编译新计划,从而保证最佳执行计划。由于在运行时编译新计划非常快,因此动态 SQL 可能会胜过参数查询。

来源http ://www.utteraccess.com/wiki/index.php/Parameter_Query#Performance

另外,如果我不得不猜测,在您的参数查询中,Access 正在从 Oracle 请求整个表,然后使用您的 where 子句进行过滤,但是当指定 WHERE 子句时,它实际上只是加载这些记录并可能使用索引.

至于解决方案,我会在 VBA 中构建您的查询字符串,然后执行它。它使您可以进行注射,但是您可以处理。所以:

不要在 Access 中使用保存的参数查询对象,而是尝试执行类似的操作。

 dim qr as string
 qr = "SELECT * FROM myTable WHERE myDate = #" & me.dateControl & "#;"

'CurrentDb.execute qr, dbFailOnError

  Docmd.RunSQL qr

或者,正如您回答的那样, currentdb.openrecordset(qr) 这将迫使引擎在运行时制定执行计划,而不是保存可能不是最佳的计划。让我知道这是否适合你,我很想看看。

于 2013-04-15T19:43:35.400 回答
0

当然,上面关于在 Access (JET/ACE) 中使用参数的参考仅适用于访问后端,而不适用于 SQL server 或 oracle 等 ODBC 后端。由于您指出您在此处使用 Oracle,然后创建视图或使用传递查询将并且应该解决此性能问题。但是,不希望将 Access/JET 参数与来自某些基于服务器的系统的数据一起使用——您最好只发送服务器 SQL 字符串,但更好的是使用传递查询。如果结果集需要编辑,那么 PT 查询是只读的,您必须创建一个视图并链接到该视图。

于 2015-03-30T00:56:50.920 回答