Hi,
I have a query used for paging that is running very fast in 0 seconds (records returned are 2000 // param char_field2='26752'),
but slow more than 12 seconds when changed param (records returned 95 //param char_field2='27622') just replaced the param char_field2='26752' to char_field2='27622', all else are identical. I checked the executions plans they are different.
Would any one pls. explain this although first query returns more records?

first query
select * from ( select docno from (select top 15 docno from FINANCE_MAIN m where CHAR_FIELD2='26752' AND CHAR_FIELD3='89715' AND CHAR_FIELD4='89716' AND CHAR_FIELD6='16000' AND CHAR_FIELD7='16003' Order by docno desc) as t1 where not exists ( select * from (select top 0 docno from FINANCE_MAIN m where CHAR_FIELD2='26752' AND CHAR_FIELD3='89715' AND CHAR_FIELD4='89716' AND CHAR_FIELD6='16000' AND CHAR_FIELD7='16003' Order by docno desc) as t2 where t1.docno=t2.docno )) as t3 inner join( select top 10000000 INDOCNO,CHAR_FIELD2,CHAR_FIELD3_AR,CHAR_FIELD1_AR,CHAR_FIELD4_AR,convert(nvarchar,FORWARD_DATE,103) as FORWARD_DATE,SUBJECT,COALESCE(DC2.parent_DOCNO,DC1.parent_DOCNO) AS ISLINKED,att.docno as attach,m.docno as docno,m.confid_id as confid,f.docname ,CHAR_FIELD3 from FINANCE_MAIN m left outer join (select top 1000000 max(cast (parent_docno as int) ) as parent_docno from oaefile_doclinks group by parent_docno order by parent_docno desc) as DC1 on m.docno=dc1.parent_docno LEFT OUTER JOIN OAEFILE_DOCLINKS DC2 ON m.DOCNO=DC2.CHILD_DOCNO LEFT OUTER JOIN (select top 1000000 cast (t.docno as int) as docno,min(f.docid) as attach_docno from dmsdocinfo f inner join FINANCE_ATTACH t on f.docid=t.attach_docno group by docno order by docno desc) as att on m.docno=att.docno left outer join dmsdocinfo f on att.attach_docno=f.docid where CHAR_FIELD2='26752' AND CHAR_FIELD3='89715' AND CHAR_FIELD4='89716' AND CHAR_FIELD6='16000' AND CHAR_FIELD7='16003' Order by docno desc ) as t4 on t3.docno=t4.docno order by t3.docno desc

second query
select * from ( select docno from (select top 15 docno from FINANCE_MAIN m where CHAR_FIELD2='27622' AND CHAR_FIELD3='89715' AND CHAR_FIELD4='89716' AND CHAR_FIELD6='16000' AND CHAR_FIELD7='16003' Order by docno desc) as t1 where not exists ( select * from (select top 0 docno from FINANCE_MAIN m where CHAR_FIELD2='27622' AND CHAR_FIELD3='89715' AND CHAR_FIELD4='89716' AND CHAR_FIELD6='16000' AND CHAR_FIELD7='16003' Order by docno desc) as t2 where t1.docno=t2.docno )) as t3 inner join( select top 10000000 INDOCNO,CHAR_FIELD2,CHAR_FIELD3_AR,CHAR_FIELD1_AR,CHAR_FIELD4_AR,convert(nvarchar,FORWARD_DATE,103) as FORWARD_DATE,SUBJECT,COALESCE(DC2.parent_DOCNO,DC1.parent_DOCNO) AS ISLINKED,att.docno as attach,m.docno as docno,m.confid_id as confid,f.docname ,CHAR_FIELD3 from FINANCE_MAIN m left outer join (select top 1000000 max(cast (parent_docno as int) ) as parent_docno from oaefile_doclinks group by parent_docno order by parent_docno desc) as DC1 on m.docno=dc1.parent_docno LEFT OUTER JOIN OAEFILE_DOCLINKS DC2 ON m.DOCNO=DC2.CHILD_DOCNO LEFT OUTER JOIN (select top 1000000 cast (t.docno as int) as docno,min(f.docid) as attach_docno from dmsdocinfo f inner join FINANCE_ATTACH t on f.docid=t.attach_docno group by docno order by docno desc) as att on m.docno=att.docno left outer join dmsdocinfo f on att.attach_docno=f.docid where CHAR_FIELD2='27622' AND CHAR_FIELD3='89715' AND CHAR_FIELD4='89716' AND CHAR_FIELD6='16000' AND CHAR_FIELD7='16003' Order by docno desc ) as t4 on t3.docno=t4.docno order by t3.docno desc

I'm amazed it runs in a reasonable time at all with all the nested sub-selects ...

For example, what's the purpose of this?

LEFT OUTER JOIN
(
select top 1000000 cast (t.docno as int) as docno, min(f.docid) as attach_docno
from dmsdocinfo f
inner join FINANCE_ATTACH t
on f.docid=t.attach_docno
group by docno
order by docno desc
) as att
on m.docno=att.docno

Casting the docno to INT in order to then make the join, having to pre-prepare this for the GROUP BY and forcing a sort to get the TOP 1000000 - surely a JOIN would be able to sort all that out, more efficiently, without all that paraphernalia?

It all looks like horribly tangled to me. The whole query is on one line too, don't know how many people here will bother to read it unformatted, nor whether I have spotted anything useful, or have just focus on irrelevant points, from my quick look at it

Thank you for your comment I agree with you for the bad chosen query,
unfortunately I have inherited the system and profiling it showed me this query used for paging and they should have used top and offset for paging instead.
I have control only to the Db and trying to tune the paging by creating indexes, I don't know if I can force to use a plan for a query from the DB only.

first he try to get the rows for the page he is on by
select top 30 docno from maintable where ... not exist in (select top 15 docno from maintable where ..) // so he will get the 15 doc nos. for the second page.
then he join this table with itself and other tables to get the extra columns.
but Iam surprised why its choosing diff plan for different values of the parameter.

formatted query

select *
from ( select docno
from (select top 15 docno from FINANCE_MAIN m
where ....
Order by docno desc) as t1
where not exists ( select *
from (select top 0 docno
from FINANCE_MAIN m
where ...
Order by docno desc
) as t2
where t1.docno=t2.docno
)
) as t3
inner join ( select top 10000000 INDOCNO,CHAR_FIELD2,CHAR_FIELD3_AR,CHAR_FIELD1_AR,CHAR_FIELD4_AR,convert(nvarchar,FORWARD_DATE,103) as FORWARD_DATE,SUBJECT,COALESCE(DC2.parent_DOCNO,DC1.parent_DOCNO) AS ISLINKED,att.docno as attach,m.docno as docno,m.confid_id as confid,f.docname ,CHAR_FIELD3
from FINANCE_MAIN m
left outer join (select top 1000000 max(cast (parent_docno as int) ) as parent_docno from oaefile_doclinks group by parent_docno order by parent_docno desc) as DC1 on m.docno=dc1.parent_docno
LEFT OUTER JOIN OAEFILE_DOCLINKS DC2 ON m.DOCNO=DC2.CHILD_DOCNO
LEFT OUTER JOIN (select top 1000000 cast (t.docno as int) as docno,min(f.docid) as attach_docno from dmsdocinfo f
inner join FINANCE_ATTACH t on f.docid=t.attach_docno group by docno order by docno desc) as att on m.docno=att.docno
left outer join dmsdocinfo f on att.attach_docno=f.docid where CHAR_FIELD2='26752' AND CHAR_FIELD3='89715' AND CHAR_FIELD4='89716' AND CHAR_FIELD6='16000' AND CHAR_FIELD7='16003' Order by docno desc ) as t4 on t3.docno=t4.docno
order by t3.docno desc