[AccessD] Basic Query Design: Results

Jürgen Welz jwelz at hotmail.com
Fri Feb 10 14:54:08 CST 2006


Had to try the speed comparisons between the three approaches to querying 
"Every Employee who has taken all of the following 4 courses".  Tables are 
tblEmployee, tblEmployeeCourse (junction table) and tblCourse.  There are 
1700 employees, about 2000 EmployeeCourse records and 18 course records.

1.  Using Count: qryTestCount

SELECT tblEmployeeCourse.EmployeeID, FirstName & ' ' & LastName AS Estimator
FROM tblEmployeeCourse INNER JOIN tblEmployee ON 
tblEmployeeCourse.EmployeeID = tblEmployee.ContactID
WHERE (((tblEmployeeCourse.CourseID) In (1,2,4,5)))
GROUP BY tblEmployeeCourse.EmployeeID, FirstName & ' ' & LastName
HAVING (((Count(tblEmployee.ContactID)) = 4))
ORDER BY FirstName & ' ' & LastName;

2.  Nested Selects: qryTestNestedIn

SELECT DISTINCT ContactID, FirstName & ' ' & LastName
FROM tblEmployeeEmployeeType RIGHT JOIN tblEmployee ON 
tblEmployeeEmployeeType.EmployeeID = tblEmployee.ContactID
WHERE tblEmployee.ContactID > 0 And tblEmployee.Deleted = False And 
FirstName > '' And LastName > ''  And ContactID In (Select ContactID FROM 
tblEmployee INNER JOIN tblEmployeeCourse ON tblEmployee.ContactID = 
tblEmployeeCourse.EmployeeID Where ContactID In (Select ContactID FROM 
tblEmployee INNER JOIN tblEmployeeCourse ON tblEmployee.ContactID = 
tblEmployeeCourse.EmployeeID Where ContactID In (Select ContactID FROM 
tblEmployee INNER JOIN tblEmployeeCourse ON tblEmployee.ContactID = 
tblEmployeeCourse.EmployeeID Where ContactID In (Select ContactID FROM 
tblEmployee INNER JOIN tblEmployeeCourse ON tblEmployee.ContactID = 
tblEmployeeCourse.EmployeeID Where CourseID = 1) And CourseID = 2) And 
CourseID = 5) And CourseID = 4)
ORDER BY FirstName & ' ' & LastName;

3.  Relational Division:  qryTestRelationalDiv

SELECT DISTINCT EC1.EmployeeID, [FirstName] & " " & [LastName] AS Expr1
FROM tblEmployeeCourse AS EC1 INNER JOIN tblEmployee ON EC1.EmployeeID = 
tblEmployee.ContactID
WHERE (((Exists (SELECT CourseID FROM tblCourse   WHERE CourseID In 
(1,2,4,5) AND NOT EXISTS      ( SELECT * FROM tblEmployeeCourse AS EC2       
   WHERE EC2.CourseID = tblCourse.CourseID         AND EC2.EmployeeID = 
EC1.EmployeeID)))=False))
ORDER BY [FirstName] & " " & [LastName];

The following subroutine was used to open each query in sequence and report 
to the debug window:

Public Declare Function timeGetTime Lib "Winmm" () As Long

Sub testQuerySpeed()
    Dim r As DAO.Recordset
    Dim db As DAO.Database
    Dim lngi As Long
    Dim t As Long

    Set db = CurrentDb
    t = timeGetTime
    For lngi = 0 To 50
        Set r = db.OpenRecordset("qryTestCount")
    Next
    Debug.Print "Using Count " & timeGetTime - t
    t = timeGetTime
    For lngi = 0 To 50
        Set r = db.OpenRecordset("qryTestNestedIn")
    Next
    Debug.Print "Using Nested Join " & timeGetTime - t
    t = timeGetTime
    For lngi = 0 To 50
        Set r = db.OpenRecordset("qryTestRelationalDiv")
    Next
    Debug.Print "Using RelationalDivision " & timeGetTime - t
    r.Close
    Set r = Nothing
End Sub

The results in the immediate window (in milliseconds), run 5 minutes apart 
speak for themselves:

Using Count 5219
Using Nested Join 34796
Using RelationalDivision 13563

Using Count 7750
Using Nested Join 53625
Using RelationalDivision 17000

Ciao
Jürgen Welz
Edmonton, Alberta
jwelz at hotmail.com





More information about the AccessD mailing list