Reputation: 41
I have one performance issue on a huge SQL Server table. We have this query:
SELECT cycle
FROM product AS pr
INNER JOIN productdetails AS prd
ON prd.label = 'XRT354511'
AND ( pr.cycle = prd.cycle OR prd.cycle LIKE pr.cycle+ '-EXECUTED%' )
Condition after OR statement is using like to concatenate product table cycle with -EXECUTED (We don't care about the '-EXECUTED' position in cycle, we just need to know if the cycle contains -EXECUTED).
Then, my proposal to fix this issue is change that query for this one:
SELECT cycle
FROM product AS pr
INNER JOIN productdetails AS prd
ON prd.label = 'XRT354511'
AND ( pr.cycle = prd.cycle
OR (pr.cycle = prd.cycle AND pr.cycle LIKE '-EXECUTED%'))
When i executed second query, it runs pretty fast and smooth.
Is my proposal valid, Can i use my proposal and get the same results than first query?
Thanks
Upvotes: 0
Views: 108
Reputation: 5060
Your question: "Is my proposal valid, Can i use my proposal and get the same results than first query?"
No, they are not the same. Let's rewrite your two queries in following way, so we can concentrate on join condition:
SELECT cycle
FROM product AS pr
INNER JOIN productdetails AS prd ON pr.cycle = prd.cycle OR prd.cycle LIKE pr.cycle+ '-EXECUTED%'
WHERE prd.label = 'XRT354511' ;
and
SELECT cycle
FROM product AS pr
INNER JOIN productdetails AS prd ON pr.cycle = prd.cycle
OR (pr.cycle = prd.cycle AND pr.cycle LIKE '-EXECUTED%')
WHERE prd.label = 'XRT354511' ;
The first condition is
pr.cycle = prd.cycle OR prd.cycle LIKE pr.cycle+ '-EXECUTED%'
The second (your proposal) is
pr.cycle = prd.cycle
OR (pr.cycle = prd.cycle AND pr.cycle LIKE '-EXECUTED%')
This latter is equivalent to
pr.cycle = prd.cycle OR pr.cycle LIKE '-EXECUTED%
As you can see easily in this simplified form, in the first you look for (eg. if pr.cycle='100') '100' and '100-EXECUTED%'. In the latter you look for '100' (or pr.cycle LIKE 'EXECUTED%')
If you post sample data, I can try to see results with you and try analyze performances.
Upvotes: 1
Reputation: 4058
the answer to your 1st question is NO, your solution will get diiferent results than original query
to optimize the query you should analyze which indexes are active on your product and productdetails tables..
you can try;
SELECT cycle
FROM product AS pr
INNER JOIN productdetails AS prd ON pr.cycle = prd.cycle
WHERE prd.label = 'XRT354511'
UNION ALL
SELECT cycle
FROM product AS pr
INNER JOIN productdetails AS prd
ON SUBSTRING(prd.cycle, 1, LEN(pr.cycle)+9) COLLATE LATIN1_GENERAL_BIN = (pr.cycle + '-EXECUTED') COLLATE LATIN1_GENERAL_BIN
WHERE prd.label = 'XRT354511'
AND pr.cycle <> prd.cycle
This will split it in two queries, the 1st will probably use an index and the 2nd should be slight fast then the like operator
But you also told that the position of "-EXECUTED"
should not be important in productdetails.cycle
In this case you need to change the 2nd join condition to
ON prd.cycle COLLATE LATIN1_GENERAL_BIN LIKE (pr.cycle + '-%-EXECUTED%') COLLATE LATIN1_GENERAL_BIN
please note the "-%"
before "-EXECUTED"
also note the last condition of 2nd query, you COULD try to change the UNION ALL
with a simple UNION
and remove AND pr.cycle <> prd.cycle
Upvotes: 0
Reputation: 13393
Could you change OR
part with this one?
OR (pr.cycle = LEFT(prd.cycle, LEN(pr.cycle)) AND prd.cycle LIKE '%-EXECUTED%')
Upvotes: 1