I have a wpf mvvm application that records phone call queries and advice.
I am trying to query the call records for information in related entities, but performance is slow.
Call--1:M--CallQuery--M:M--AnswerDoc--1:M--AnswerDocSection
1:M|M:1
CallQueryAnswerDoc
So, a call will have one or more queries (a query is a question and its answer), and (the answer to) a query will refer to 1 or more (max 2) AnswerDocsSections. Each AnswerDocSection comes from an AnswerDoc. The CallQueryAnswerDoc table is created to deal with the M:M join between the CallQuery and AnswerDoc tables.
To prepare an FAQ, I'm trying to query which calls used certain AnswerDocs and/or AnswerDocSections.
For my first approach, I retrieved an ObservableCollection
of Calls, then looped through each call to collect an ObservableCollection
of its CallQueries, and for each CallQuery, check if the AnswerDocID matches the searchText's AnswerDocID. If so, the Call is added to the returned list of calls.
In a database of about 5k calls, this takes well over ten minutes and proceeds through Calls at about 100 per 10 seconds.
So, next I tried to do it all in a linq query using a syntax like:
var qCQADS = callList.Where(c =>
c.CallQueries.Any(cq =>
cq.CallQueryAnswerDocs.Any(cqad =>
cqad.AnswerDocSectionID == CallSearch.AnswerDocSectionID)));
but surprisingly (to me, anyway) this seems to take as much time as new
ing up ObservableCollections
.
I can do this query in sql and get results in under 1 second.
SQL query
SELECT dbo.AnswerDoc.Code, dbo.AnswerDocSection.Title, dbo.Call.CallID,
dbo.Call.CallDate, dbo.Call.RegionID, dbo.Call.CallSubject
FROM dbo.AnswerDocSection
INNER JOIN dbo.CallQueryAnswerDocSection ON dbo.AnswerDocSection.AnswerDocSectionID =
dbo.CallQueryAnswerDocSection.AnswerDocSectionID
INNER JOIN dbo.CallQuery ON dbo.CallQueryAnswerDocSection.CallQueryID =
dbo.CallQuery.CallQueryID
INNER JOIN dbo.AnswerDoc ON dbo.AnswerDocSection.AnswerDocID = dbo.AnswerDoc.AnswerDocID
INNER JOIN dbo.Call ON dbo.CallQuery.CallID = dbo.Call.CallID
WHERE (dbo.AnswerDoc.Code = N'General')
AND (dbo.AnswerDocSection.Title = N'Invalid Username')
How do I approach this performance using wpf?