Steve Erbach
erbachs at gmail.com
Sun Feb 12 12:32:43 CST 2006
Jürgen,
Now, the $64,000 question: Did all the queries give you the same results?
Just kidding! I'm interested to see that the Count query is quickest.
It's certainly easier to understand...and should make for a lot less
coding!
Steve Erbach
Neenah, WI
http://TheTownCrank.blogspot.com
On 2/10/06, Jürgen Welz <jwelz at hotmail.com> wrote:
> Of course, after I posted, I had to try another method.
>
> The query is:
>
> SELECT tblEmployee.ContactID, [FirstName] & ' ' & [LastName] AS Expr1
> FROM (((tblEmployee INNER JOIN tblEmployeeCourse ON tblEmployee.ContactID =
> tblEmployeeCourse.EmployeeID) INNER JOIN tblEmployeeCourse AS
> tblEmployeeCourse_1 ON tblEmployeeCourse.EmployeeID =
> tblEmployeeCourse_1.EmployeeID) INNER JOIN tblEmployeeCourse AS
> tblEmployeeCourse_2 ON tblEmployeeCourse.EmployeeID =
> tblEmployeeCourse_2.EmployeeID) INNER JOIN tblEmployeeCourse AS
> tblEmployeeCourse_3 ON tblEmployeeCourse.EmployeeID =
> tblEmployeeCourse_3.EmployeeID
> WHERE (((tblEmployeeCourse.CourseID)=1) AND
> ((tblEmployeeCourse_1.CourseID)=2) AND ((tblEmployeeCourse_2.CourseID)=4)
> AND ((tblEmployeeCourse_3.CourseID)=5))
> ORDER BY [FirstName] & ' ' & [LastName];
>
>
> This is functionally equivalent to creating a query select where CourseID
> =1, another where CourseID = 2, a third where CouseID = 4 and a 4th where
> course ID = 5 and then joining them all on the ContactID.
>
> A few runs of the time test adding this as a 4th test item result in a time
> that is 2nd fastest but consistently 70% slower than the fastest method that
> uses the count.
>
>
> Ciao
> Jürgen Welz
> Edmonton, Alberta
> jwelz at hotmail.com
>
>
>
>
>
> >From: "Jürgen Welz" <jwelz at hotmail.com>
> >
> >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
> >
> >
>
>
> >--
> >AccessD mailing list
> >AccessD at databaseadvisors.com
> >http://databaseadvisors.com/mailman/listinfo/accessd
> >Website: http://www.databaseadvisors.com
>
>
>
>
> --
> AccessD mailing list
> AccessD at databaseadvisors.com
> http://databaseadvisors.com/mailman/listinfo/accessd
> Website: http://www.databaseadvisors.com
>
>
>
--
Regards,
Steve Erbach
Scientific Marketing
Neenah, WI
www.swerbach.com
Security Page: www.swerbach.com/security