Reputation: 23
I have the following query that takes several seconds to run:
SELECT COUNT(*) cnt
FROM [PTYCHRG] A, [AVAIL_ACTION_TYPE_CODES_TEMP] B
WHERE TRIM(A.CASE_ID) = TRIM(caseid)
AND TRIM(B.casecode) = TRIM(casecd)
AND (
TRIM(A.ACTN_CD) = TRIM(B.ACTIONCODE)
OR TRIM(A.INDICTED_ACTN_CD) = TRIM(B.ACTIONCODE)
OR TRIM(A.AMENDED_ACTN_CD) = TRIM(B.ACTIONCODE)
)
AND LOWER(TRIM(B.DOMAIN)) = LOWER(TRIM(domain))
AND [rownum] = 1;
I'm looking for a way/method to speed it up significantly as it is a part of a larger process.
I am basically looking to see if there is at least one record (I don't care what field I pull back, I just want to know if there is at least one record).
Any ideas on what I can do different to make it run faster?
Upvotes: 1
Views: 79
Reputation: 1271003
This is your query rewritten with proper join
syntax, better table aliases, and fewer parentheses::
SELECT COUNT(*) cnt
FROM PTYCHRG p JOIN
AVAIL_ACTION_TYPE_CODES_TEMP atc
ON TRIM(p.CASE_ID) = TRIM(atc.caseid) AND
TRIM(atc.casecode) = TRIM(p.casecd) AND
TRIM(atc.ACTIONCODE) IN (TRIM(p.ACTN_CD), TRIM(p.INDICTED_ACTN_CD), TRIM(p.AMENDED_ACTN_CD)) AND
LOWER(TRIM(atc.DOMAIN)) = LOWER(TRIM(p.domain)) AND
WHERE rownum = 1;
None of these fix any problems. Instead, they make it easier to higlight problems. First, you are running functions on values. This usually prevents SQL Server from using indexes, or even making more informed decisions about joins. If spaces are really a problem, there are two solutions: a functional index or fix the data. I would go with fixing the data:
update PTYCHRG
set Case_Id = TRIM(Case_id),
ActionCode = TRIM(ActionCode),
ACTN_CD = TRIM(ACTN_CD),
INDICTED_ACTN_CD = TRIM(INDICTED_ACTN_CD),
AMENDED_ACTN_CD = TRIM(AMENDED_ACTN_CD),
domain = lower(trim(domain));
update AVAIL_ACTION_TYPE_CODES_TEMP
set caseid = trim(caseid),
casecode = trim(casecode)
ACTIONCODE = trim(ACTIONCODE),
domain = lower(trim(domain));
Then the query becomes:
SELECT COUNT(*) cnt
FROM PTYCHRG p JOIN
AVAIL_ACTION_TYPE_CODES_TEMP atc
ON p.CASE_ID = atc.caseid AND
atc.casecode = p.casecd AND
atc.ACTIONCODE IN (p.ACTN_CD, p.INDICTED_ACTN_CD, p.AMENDED_ACTN_CD) AND
atc.DOMAIN = p.domain AND
WHERE rownum = 1;
And then I would recommend indexes. You can try:
create index idx_AVAIL_ACTION_TYPE_CODES_TEMP_4
on AVAIL_ACTION_TYPE_CODES_TEMP(caseid, casecode, domain, actioncode)
Upvotes: 1
Reputation: 6071
Ryan
Can you see, whether the SQL gives same result as yours.
SELECT COUNT(*) cnt
FROM [PTYCHRG] A
JOIN [AVAIL_ACTION_TYPE_CODES_TEMP] B
ON TRIM(A.CASE_ID) = TRIM(caseid)
AND ISNULL(TRIM(A.ACTN_CD),ISNULL(TRIM(A.INDICTED_ACTN_CD),TRIM(A.AMENDED_ACTN_CD))) = TRIM(B.ACTIONCODE)
WHERE [rownum] = 1
If avoidable, remove TRIM()
from the sql as well
Upvotes: 0