我希望之前没有问到这里(我在这里搜索过,并且谷歌找了答案,但找不到答案)
问题是:我使用MS Access 2010从链接表中选择记录(表中有数百万条记录)。如果我直接指定条件(例如Date)(例如date =#1/1/2013#),则查询会立即返回。如果我使用参数(添加日期/时间类型的参数并在提示时提供值1/1/2013(或以某种不同格式提供日期),或在表单中引用控件),则查询需要几分钟才能加载。 / p>
如果您对导致此问题的原因有任何疑问,请与我们联系。对于提出这样一个问题并且可能浪费某些时间我感到很难过......
答案 0 :(得分:2)
这是一个潜在的答案,我自己也不知道,并做了一点挖掘。
如果性能很重要,那么由于查询的优化方式,即使参数查询适合,也可能需要优先选择动态SQL。通常,Access会在保存时为新查询创建计划。 当查询包含参数时,Access无法知道参数可能包含的值,并且必须进行“好猜”。根据以后提供的实际值,它可能好或差,导致性能不佳。相比之下,动态SQL会回避这一点,因为“参数”被硬编码到临时字符串中因此,使用该值编制新计划,保证最佳执行计划。由于在运行时编译新计划的速度非常快,因此动态SQL的性能可能优于参数查询。
来源:http://www.utteraccess.com/wiki/index.php/Parameter_Query#Performance
此外,如果我必须猜测,在您的参数查询中,Access正在从Oracle请求ENTIRE表,然后使用您的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)
这将迫使引擎在运行时制定执行计划,而不是保存可能不太理想的计划。让我知道如果这对你有用,我有兴趣看看。
答案 1 :(得分:0)
当然,上面有关使用Access(JET / ACE)参数的参考仅适用于访问后端,而不适用于SQL服务器或oracle等ODBC。由于您指出在此处使用Oracle然后创建视图或使用pass-though查询将会并且应该解决此性能问题。但是,人们不希望将Access / JET参数与来自某个基于服务器的系统的数据一起使用 - 您最好只发送服务器SQL字符串,但更好的方法是使用pass-though查询。如果结果集需要编辑,则PT查询只是只读,您必须创建一个视图并链接到该视图。