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 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.
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
or a parameter:
select foo.f1, foo.f2, foo.f3
from foo
where foo.f4 = [myFooF4]
or with a join:
select foo.f1, foo.f2, foo.f3
from foo
INNER JOIN bar ON bar.myF4 = foo.f4
It runs much faster.
Why?
Specs: App written and running in MS Access 2003, back-end database is SQL Server 2008.
INNER JOINquery is. Can you really not see how forcing a particular plan (e.g. requiring a second connection to lookup a value in a table) is not allowing the optimizer do its job?