From: tshad on
If you are doing paging you need to pass back the total number of rows of
the query.

What is the best way to do that?

What one person does is do the SELECT/INTO a temp table to get the total
number of rows.

Then he does a "SET ROWCOUNT @RowNumber", then does a SELECT * ...

The problem here is that he is using doing an insert into a temp table with
2 selects (one to insert and one to pass back the results).

What I do is have 2 functions (could do it in one with a parameter) that
have identical queries except
1) in one I have all the columns I want to return and in the other I have a
SELECT using the ROW_NUMBER() function. I have to do it this way because
the number of @@ROWCOUNT will be equal to the number of rows from your
"WHERE ResultSetNumber BETWEEN @StartRow and @EndRow" clause not the number
of the total result set.
2) in the other I have a "SELECT Count(*)" with the rest of the query the
same as #1.

Is there a better way to do this?

Thanks,

Tom


From: Plamen Ratchev on
You can do it in a single query:

SELECT <columns>, rk, total_count
FROM (
SELECT <columns>,
ROW_NUMBER() OVER... AS rk,
COUNT(*) OVER() AS total_count
FROM Foo) AS F
WHERE rk BETWEEN @page_start AND @page_end;

--
Plamen Ratchev
http://www.SQLStudio.com
From: tshad on
That worked pretty well.

I had never seen the COUNT(*) OVER() before. Is it new?

But it does add some overhead.

I am trying to optimize a query that was doing a FULL JOIN into a temp table
(to get the Total Count) then does a SET ROWCOUNT followed by a SELECT *...
from the temporary table.

Doing that the profiler was showing 340400 Reads.

I got rid of the Temporary table and got the number of reads down to 339110
reads (about 10,000 reads less).

But when I added the COUNT(*) OVER() to the SELECT - it went up to 339,900
(not sure why that is).

I am still trying to see if I can get rid of the JULL JOIN. I noticed it was
doing a couple of Hash Matches (right outer join) but the cost was only 1%
and 2% but there was a couple Nested Loops (Left Semi Join) - one was 21%.

Thanks,

Tom

"Plamen Ratchev" <Plamen(a)SQLStudio.com> wrote in message
news:hYGdndk2a5qi1jDWnZ2dnUVZ_gKdnZ2d(a)speakeasy.net...
> You can do it in a single query:
>
> SELECT <columns>, rk, total_count
> FROM (
> SELECT <columns>,
> ROW_NUMBER() OVER... AS rk,
> COUNT(*) OVER() AS total_count
> FROM Foo) AS F
> WHERE rk BETWEEN @page_start AND @page_end;
>
> --
> Plamen Ratchev
> http://www.SQLStudio.com


From: Plamen Ratchev on
COUNT() OVER() was added in SQL Server 2005, together with the ranking functions. The OVER clause supports the other
aggregate functions too (SUM, MIN, MAX, AVG).

If you are talking about logical reads then it may not be an issue. See more here:
http://www.sql-server-performance.com/articles/per/logical_reads_p1.aspx

--
Plamen Ratchev
http://www.SQLStudio.com
From: Erland Sommarskog on
tshad (tfs(a)dslextreme.com) writes:
> I had never seen the COUNT(*) OVER() before. Is it new?
>
> But it does add some overhead.
>
> I am trying to optimize a query that was doing a FULL JOIN into a temp
> table (to get the Total Count) then does a SET ROWCOUNT followed by a
> SELECT *... from the temporary table.
>
> Doing that the profiler was showing 340400 Reads.
>
> I got rid of the Temporary table and got the number of reads down to
> 339110 reads (about 10,000 reads less).
>
> But when I added the COUNT(*) OVER() to the SELECT - it went up to 339,900
> (not sure why that is).

I wouldn't say that 340400, 339900 or 339110 are all the same to me.

And what foremost matters to performance is wallclock time.

I you are going to paging, saving the result set in a session-keyed table
once, and then page from that table might be the best option. Or if the
number of rows is not excessive, just a few thousand rows, get all rows
into the client and page there.

--
Erland Sommarskog, SQL Server MVP, esquel(a)sommarskog.se

Links for SQL Server Books Online:
SQL 2008: http://msdn.microsoft.com/en-us/sqlserver/cc514207.aspx
SQL 2005: http://msdn.microsoft.com/en-us/sqlserver/bb895970.aspx
SQL 2000: http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx

 |  Next  |  Last
Pages: 1 2 3
Prev: Row_Number() Sorting
Next: Remote Access Steps