Hi,
Hum... not always, not always. I think I should start with experimental
result:
================
TestDCount
SubQuery 1.1497770068656753748608731538
DCount 0.0300636294286107324637644911
================
which clearly shows that DCount is two orders of magnitude FASTER than the
sub-query!
Sure, you now want to see the code.It uses a performance counter to
accurately time code execution of two SQL statements, equivalent, but one
using a sub-query and the other a DCount:
====================
Private Type LARGE_INTEGER
lowpart As Long
highpart As Long
End Type
Private Declare Function QueryPerformanceCounter Lib "kernel32"
(lpPerformanceCount As LARGE_INTEGER) As Long
Private Declare Function QueryPerformanceFrequency Lib "kernel32"
(lpFrequency As LARGE_INTEGER) As Long
'-------------------------------------------
Public Sub TestDCount()
Dim freq As LARGE_INTEGER
Dim starting As LARGE_INTEGER
Dim Ending As LARGE_INTEGER
Dim dfreq As Variant
QueryPerformanceFrequency freq
dfreq = LargeToDec(freq)
QueryPerformanceCounter starting
Set rst = CurrentProject.Connection.Execute("SELECT a.*, (SELECT
COUNT(*) FROM Iotas As b WHERE b.Iota>a.Iota) FROM Iotas as a;")
QueryPerformanceCounter Ending
Debug.Print "SubQuery ", (LargeToDec(Ending) - LargeToDec(starting)) /
dfreq
QueryPerformanceCounter starting
Set rst = CurrentProject.Connection.Execute("SELECT *, DCOUNT('*',
'Iotas', 'Iota>=' & Iota) FROM Iotas ;")
QueryPerformanceCounter Ending
Debug.Print "DCount ", (LargeToDec(Ending) - LargeToDec(starting)) /
dfreq
End Sub
'---------------------------------
Public Function LargeToDec(Arg As LARGE_INTEGER) As Variant
Dim temp As Variant
temp = 4 * CDec(1073741824) ' 2 ^ 32
If Arg.lowpart > 0 Then
LargeToDec = Arg.lowpart + Arg.highpart * temp
Else
LargeToDec = temp + Arg.lowpart + Arg.highpart * temp
End If
End Function
========================
where table Iotas is a large table (1 000 000 records) with one field,
iota, the primary key. With a very small table, say with one record, you
will probably get the reverse, since the string handling will kill the
DCount (its third argument involves a string creation, which is not the most
efficient operation in itself).
Now, if you wonder why DCount is almost 40 times faster than the subquery...
I would *guess* that it is because DCount is evaluated only when required,
on demand, while the sub-query is unconditionally evaluated.
Hoping it may help,
Vanderghast, Access MVP