I have two systems communicating with one another using send-acknowledge design where system 1 sends a record over to system 2 to be processed and once system 2 processes the message it will send an acknowledge message over to system 1 which changes the status from Pending -> Completed.
For example, at 1pm
Pending Records Table @ 1pm:
Record_Seq | Type | Status |
---|---|---|
1 | A | Pending |
2 | A | Pending |
3 | B | Pending |
4 | B | Pending |
5 | C | Pending |
... | ||
1000 | Z | Pending |
Acknowledge Records Table @ 1pm:
Ack_seq | Type | Record_Seq |
---|---|---|
null | null | null |
No acknowledge message received from system 2.
Acknowledge Records Table 1.05pm:
Ack_seq | Type | Record_Seq |
---|---|---|
1 | A | 1 |
2 | B | 3 |
3 | B | 4 |
4 | A | 2 |
5 | C | 5 |
... | ... |
Pending Records Table @ 1.05pm:
Record_Seq | Type | Status |
---|---|---|
1 | A | Completed |
2 | A | Completed |
3 | B | Completed |
4 | B | Completed |
5 | C | Completed |
... | ||
1000 | Z | Pending |
The problem is that sometimes system 2 does not send over the acknowledged record so records could be left pending even though they were already processed.
I wrote the following to query to try to find the records that were missing their acknowledge
-- Since total number of pending records must equal the total number of acknowledge records,
-- The query counts and check for each type of pending records and joins it with the count of each type of ack record
SELECT * FROM (
SELECT TYPE, COUNT(1) AS NUMBER_OF_PENDING FROM PENDING_RECORDS_TABLErecords
WHERE TYPE IN (SELECT DISTINCT TYPE FROM PENDING_RECORDS_TABLE)
AND STATUS = 'PENDING'
GROUP BY TYPE
) AS RECORDS_SENT
LEFT JOIN -- SO THAT I CAN GET RECORDS THAT DID NOT RECEIVE ANY ACK AT ALL
(SELECT TYPE, COUNT(1) AS NUMBER_OF_RECEIVED FROM ACKNOWLEDGE_RECORDS_TABLE
WHERE TYPE IN (SELECT DISTINCT TYPE FROM PENDING_RECORDS_TABLE)
GROUP BY TYPE
) AS ACK_RECEIVED
ON (RECORDS_SENT.TYPE = ACK_RECEIVED.TYPE)
WHERE RECORD_SENT.NUMBER_OF_PENDING <> ACK_RECEIVED.NUMBER_OF_RECEIVED
ORDER BY TYPE
The issue with this query is that it runs very slowly and if the distinct number of types > 100, it becomes exceedingly slow. How do I optimise the query so that it can run considerably faster? (Note: the size of the records and ack table are quite large)
I also encounter an issue where the query without the " WHERE RECORD_SENT.NUMBER_OF_PENDING <> ACK_RECEIVED.NUMBER_OF_RECEIVED" clause runs significantly faster than the query with this clause. I am not too sure what is causing the query to slow down because of this clause?