Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimize query in TSQL 2005

I have to optimize this query can some help me fine tune it so it will return data faster?

Currently the output is taking somewhere around 26 to 35 seconds. I also created index based on attachment table following is my query and index:

SELECT DISTINCT o.organizationlevel, o.organizationid, o.organizationname, o.organizationcode,
      o.organizationcode + ' - ' + o.organizationname AS 'codeplusname'
 FROM Organization o
 JOIN Correspondence c ON c.organizationid = o.organizationid
 JOIN UserProfile up ON up.userprofileid = c.operatorid
WHERE c.status = '4'
  --AND c.correspondence > 0
  AND o.organizationlevel = 1
  AND (up.site = 'ALL' OR
                  up.site = up.site)
  --AND (@Dept = 'ALL' OR @Dept = up.department)
  AND EXISTS (SELECT 1 FROM Attachment a
               WHERE a.contextid = c.correspondenceid
                 AND a.context = 'correspondence'
                 AND ( a.attachmentname like '%.rtf' or  a.attachmentname like '%.doc'))
ORDER BY o.organizationcode

I can't just change anything in db due to permission issues, any help would be much appreciated.

like image 622
aspmvcdeveloper Avatar asked Nov 20 '25 18:11

aspmvcdeveloper


1 Answers

I believe your headache is coming from this part in specific...like in a where exists can be your performance bottleneck.

 AND EXISTS (SELECT 1 FROM Attachment a
           WHERE a.contextid = c.correspondenceid
             AND a.context = 'correspondence'
             AND ( a.attachmentname like '%.rtf' or  a.attachmentname like '%.doc'))

This can be written as a join instead.

SELECT DISTINCT o.organizationlevel, o.organizationid, o.organizationname, o.organizationcode,
  o.organizationcode + ' - ' + o.organizationname AS 'codeplusname'
FROM Organization o
JOIN Correspondence c ON c.organizationid = o.organizationid
JOIN UserProfile up ON up.userprofileid = c.operatorid
left join article a on a.contextid = c.correspondenceid
             AND a.context = 'correspondence'
             and right(attachmentname,4) in ('.doc','.rtf')

....

This eliminates both the like and the where exists. put your where clause at the bottom.it's a left join, so a.anycolumn is null means the record does not exist and a.anycolumn is not null means a record was found. Where a.anycolumn is not null will be the equivalent of a true in the where exists logic.

Edit to add: Another thought for you...I'm unsure what you are trying to do here...

AND (up.site = 'ALL' OR up.site = up.site)

so where up.site = 'All' or 1=1? is the or really needed?

and quickly on right...Right(column,integer) gives you the characters from the right of the string (I used a 4, so it'll take the 4 right chars of the column specified). I've found it far faster than a like statement runs.

like image 105
Twelfth Avatar answered Nov 22 '25 17:11

Twelfth