Showing posts with label paging. Show all posts
Showing posts with label paging. Show all posts

Tuesday, March 20, 2012

Paging, Soring, Filtering Already-written SPs Result

Hi guys,
we developed a large-scale web-application which uses sqlserver 2005,
and we created all of SPs for geting list of particular records or
geting a record info.
i.e Products_GetList | Products_GetInfo & etc.
now we need to implement paging,sorting or filtering on these SPs
results...
& we couldn't do this at webapplication level because of huge number of
records... also it's not possible to change all of these SPs(we have
more than 300 SPs already)
in other words i'm searching for a way to create a generic method(SP or
UDF) which do the paging & other operations on result of all SPs if
required.
i.e :
MyApp --> DAL --> Call Specific SP with Specific Sorting --> DB -->
[Generic SP (do sorting)] --> Specific SP
ThanksHi
http://databases.aspfaq.com/database/how-do-i-page-through-a-recordset.html
"Khafancoder" <khafancoder@.gmail.com> wrote in message
news:1168506782.577051.145700@.k58g2000hse.googlegroups.com...
> Hi guys,
> we developed a large-scale web-application which uses sqlserver 2005,
> and we created all of SPs for geting list of particular records or
> geting a record info.
> i.e Products_GetList | Products_GetInfo & etc.
> now we need to implement paging,sorting or filtering on these SPs
> results...
> & we couldn't do this at webapplication level because of huge number of
> records... also it's not possible to change all of these SPs(we have
> more than 300 SPs already)
> in other words i'm searching for a way to create a generic method(SP or
> UDF) which do the paging & other operations on result of all SPs if
> required.
> i.e :
> MyApp --> DAL --> Call Specific SP with Specific Sorting --> DB -->
> [Generic SP (do sorting)] --> Specific SP
>
> Thanks
>|||IMO the solution is to redesign, rather than attempt a workaround. You might
think you could use wrapper procedure calls for each stored proc which
caches the results in a temp table and sorts them but the syntax for this is
"insert into #yourtable exec yourproc", so the temp table definition must
already exist and each wrapper proc will therefore be different. Whichever
way you look at it, this will require widespread changes. The sorted column
will need to be provided, and as you are using paging, the page size and
page number will be provided. So, new parameters will get added to each
stored proc call from the application and each stored proc needs editing.
Cheers,
Paul Ibison SQL Server MVP, www.replicationanswers.com .|||Thanks,
yes, as u said this wrapper method (i.e for sorting) should get
SortColumnName, Asc|Desc and SP name...
if we ignore the temp-table structure problem, other problems will
solved, for example if all of these SPs return a resultset in a
specific format then the wrapper method could insert them in a generic
temp-table and sort them and finally return them.
in this approach i can call "insert into #generictemptable exec SPName"
dynamically by using execute cmd, but i think it will affect on
application performance...
how about CLR Integration ? could we use it to write the wrapper ?
Paul Ibison wrote:
> IMO the solution is to redesign, rather than attempt a workaround. You might
> think you could use wrapper procedure calls for each stored proc which
> caches the results in a temp table and sorts them but the syntax for this is
> "insert into #yourtable exec yourproc", so the temp table definition must
> already exist and each wrapper proc will therefore be different. Whichever
> way you look at it, this will require widespread changes. The sorted column
> will need to be provided, and as you are using paging, the page size and
> page number will be provided. So, new parameters will get added to each
> stored proc call from the application and each stored proc needs editing.
> Cheers,
> Paul Ibison SQL Server MVP, www.replicationanswers.com .|||My understanding of CLR integration is that it is great for iterative tasks
and pattern matching but this is pretty standard SQL so I don't see any
benefit there. In the code-behind you could use some paging code applied to
the recordset as mentioned in URI's link, but this performs badly compared
to a where clause run on the server. Essentially I'd still personally go
down the rewrite route unless your tables are incredibly generic.
Cheers,
Paul Ibison SQL Server MVP, www.replicationanswers.com .

Paging, Performance and ADODB

I want to do paging with my VB.NET app. I have a large with table
over 5 million records. I've read numerous articles on how to page
using TOP, ROW_COUNT, etc. I've tried the examples that they have
provided. Performance is fine if you are paging the "top" part of the
data set.
However, if I want to go to the last "page" of my data set, and
traverse "backwards" though it, performance is terrible. In my tests,
I have been returning 10 records a page. When I try to traverse
backwards, the best I can get is the 10 records returning in 10+
seconds for each page.
How can I do this efficiently?Oooops, forgot to mention the ADODB part.
I wrote some ADODB code in a test VB.NET app. I used a Recordset to
basically do the same thing that the paging was doing. The page of
results returned back in milliseconds for both the "front" and "back"
end of the data set.
How can I get this kind of performance? I don't want to use ADODB for
doing this.|||I meant to say ROW_NUMBER and OVER rather than ROW_COUNT in my first
post. Sorry for so many posts.

Paging, Performance and ADODB

I want to do paging with my VB.NET app. I have a large with table
over 5 million records. I've read numerous articles on how to page
using TOP, ROW_COUNT, etc. I've tried the examples that they have
provided. Performance is fine if you are paging the "top" part of the
data set.
However, if I want to go to the last "page" of my data set, and
traverse "backwards" though it, performance is terrible. In my tests,
I have been returning 10 records a page. When I try to traverse
backwards, the best I can get is the 10 records returning in 10+
seconds for each page.
How can I do this efficiently?Oooops, forgot to mention the ADODB part.
I wrote some ADODB code in a test VB.NET app. I used a Recordset to
basically do the same thing that the paging was doing. The page of
results returned back in milliseconds for both the "front" and "back"
end of the data set.
How can I get this kind of performance? I don't want to use ADODB for
doing this.|||I meant to say ROW_NUMBER and OVER rather than ROW_COUNT in my first
post. Sorry for so many posts.

Paging, Performance and ADODB

I want to do paging with my VB.NET app. I have a large with table
over 5 million records. I've read numerous articles on how to page
using TOP, ROW_COUNT, etc. I've tried the examples that they have
provided. Performance is fine if you are paging the "top" part of the
data set.
However, if I want to go to the last "page" of my data set, and
traverse "backwards" though it, performance is terrible. In my tests,
I have been returning 10 records a page. When I try to traverse
backwards, the best I can get is the 10 records returning in 10+
seconds for each page.
How can I do this efficiently?
Oooops, forgot to mention the ADODB part.
I wrote some ADODB code in a test VB.NET app. I used a Recordset to
basically do the same thing that the paging was doing. The page of
results returned back in milliseconds for both the "front" and "back"
end of the data set.
How can I get this kind of performance? I don't want to use ADODB for
doing this.
|||I meant to say ROW_NUMBER and OVER rather than ROW_COUNT in my first
post. Sorry for so many posts.

Paging with Temporary Tables

I am searching for information on paging large datasets, and have foundsome that involve creating temporary tables in the database. Before I head off and implement something, I have a number of issuesI'd like to bounce around here.
1. An example I found on MSDN involves creating a temporary table,copying relevant columns to the row in the temp table. Why dothis, rather add the source tables primary keys into the temp table,and do a join? Example; browsing Products Catalog which iscategorised into hierarchies. The MSDN version would have a temptable created with a incrementing field which is used for the paging,and then a number of fields are also copied from the products table tothe temp table - my question is why not simply copy the product primarykey into the temp table, and then join?
2. In real life, do people allow each user to create their owntemporary tables? If I have 1000 concurrent users, all wishing toperform a page-based browse, I would be creating 1000 new temporarytables. Do people consider default temp tables, that is, creatinga default temporary table for browsing each category in the productstable, for example?
3. Do you have any advice/tips for this type of problem?
Thanks!
JR.
1) I think I know what you are talking about. However, I would like to point you to another techniquethat I developed.
2) It depends what type of temporary table. The one that I use is memory resident and since it is only one column as such in memory, it's a very small trade off in resources. If they are creating the "physical" version of the temporary table, then yes, I would consider an idea that you are toying with. Essentially (just bear with me), you would just create a cross reference table to state that page X has these records... just like my inner join technique. I hate circles but at least you can see that I highlighted the most normalized way to put the pagings rather than create a whole new "physical" table to contain that information.
3) I can't think of anything other than what I just mentioned for the time being.
Regards,
Justin|||

You could try this. It uses a table variable. It takes 2 pareameters which should be self explanitory. I have tested it with a 50,000 row zipcode database and it seems to work quite well.
<code>
-- FOR MSSQL 2000

CREATE PROCEDURE dbo.Paging_sp

@.Page int,
@.RecsPerPage int

AS

SET NOCOUNT ON

DECLARE @.TableVar table (
ZipID int identity(1,1) PRIMARY KEY,
ZipCode varchar(5) NOT NULL,
City varchar(28) NOT NULL,
State varchar(50) NOT NULL )

Insert Into @.TableVar ( ZipCode, City, State )
Select ZIPCODE, CITY, STATE
From ZipCodes
ORDER BY STATE

DECLARE @.FirstRec int, @.LastRec int
SELECT @.FirstRec = (@.Page - 1) * @.RecsPerPage
SELECT @.LastRec = (@.Page * @.RecsPerPage + 1)

SELECT ZipID, ZipCode, City, State,
MoreRecords = (
SELECT COUNT(*)
FROM @.TableVar TI
WHERE TI.ZipID >= @.LastRec),
TotalPages = ( SELECT COUNT(*)/@.RecsPerPage + 1 FROM @.TableVar )
FROM @.TableVar
WHERE ZipID > @.FirstRec AND ZipID < @.LastRec

SET NOCOUNT OFF

GO
</code>

Of course there is always this:http://weblogs.sqlteam.com/jeffs/archive/2004/03/22/1085.aspx

|||Justin,
I thank you for your response. I am trying to consider andimplement your example. I looked around at many examples, and allseem to be confusingly different in implementation. My mainconcern is how well these implementations work with many concurrentusers, with a single web server and database server - theimplementation will not sit on a data center, so it needs to beperformant. From what I am seeing in the posts, all pagingsolutions come with their own caveats. I will get back to youJustin, regarding your own version. I am assuming I need to putit into a stored proc, but my db skills are not like they used tobe.
Thanks again,
Jr.
|||Hi thanks for this mail. I am working with Justins as a test run, but will keep this in mind.
Thank you.
Jr.
|||This is a silly question I know, but I have a Products table, aCategoryProducts table, and a Category table. To page, I willneed to do a join across these tables:
select a.ProductId, a.Name
from
soundleaf_products a,
soundleaf_categoryProducts b
where
b.categoryid = @.CategoryID and
b.productid = a.productid
This is really simple SQL, but from a performance place, I dont know ifthis is performant or not. I dont know how to test performance ofSQL, so any opinions on this would be very helpful.
Jr.
|||

I found you can speed up Justins solution by avoiding using a cursor like such. Especially on the lower page numbers
<code>
--## FIRST Create the Very Large Table

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[VeryLargeTable]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[VeryLargeTable]
GO

CREATE TABLE [dbo].[VeryLargeTable] (
[VLTID] [int] IDENTITY (1, 1) NOT NULL ,
[FirstName] [varchar] (25) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[LastName] [varchar] (25) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[OtherData] [varchar] (25) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
) ON [PRIMARY]
GO

--## SECOND Load some data
--## As we are adding 1 million records to the database..
--## please be patient as it could take some time.
--## If you already have a very large table to work from
--## you can use use that instead.

DECLARE @.x int
SET @.x = 1

WHILE @.x < 1000000
BEGIN
INSERT VeryLargeTable ( FirstName, LastName, OtherData )
VALUES ( 'John' + ' ' + CAST ( @.x AS varchar(100) ), 'Doe' + ' ' + CAST ( @.x AS varchar(100) ), 'YAK Stuff' + ' ' + CAST ( @.x AS varchar(100) ) )
SET @.x = @.x + 1
END

GO
--## FIFTH Create our Fast NON Cursor Procedure
CREATE PROCEDURE dbo.TestVeryLargePaging_Fast_New

@.Page int,
@.RecsPerPage int,
@.TotalPages int OUTPUT

as

set nocount on

SELECT @.TotalPages = ( SELECT COUNT(*)/@.RecsPerPage + 1 FROM VeryLargeTable )

create table #tempTable(pk int Primary Key)

Declare @.execStr varchar(2000)

Set @.execStr = 'Select top ' + convert(varchar,@.RecsPerPage) +
' VLTID from (Select top ' + convert(varchar,@.RecsPerPage*(@.page)) +
' VLTID from veryLargeTable Order By VLTID) A order by VLTID desc'

Insert into #tempTable
exec(@.execStr)

Select *
From veryLargeTable A
Join #tempTable B
On A.VLTID = B.pk

drop table #tempTable

set nocount off


GO
--## Execute the procedure
DECLARE @.Total int

EXEC dbo.TestVeryLargePaging_Fast_New 4, 500, @.Total OUTPUT

PRINT @.Total

GO
</code>
This procedure uses basically the same approach as Justins but without using a cursor.
JB

|||

A little help fromhttp://www.seventhnight.com/ and now it is screamin fast!
<code>
ALTER PROCEDURE dbo.TestVeryLargePaging_Fast_New

@.Page int,
@.RecsPerPage int,
@.TotalPages int OUTPUT

as

SELECT @.TotalPages = ( SELECT COUNT(*)/@.RecsPerPage + 1 FROM VeryLargeTable )

Declare @.execStr varchar(2000)

Set @.execStr = 'Select Z.* From veryLargeTable Z Inner Join (Select top ' + convert(varchar,@.RecsPerPage) +
' VLTID from (Select top ' + convert(varchar,@.RecsPerPage*(@.page)) +
' VLTID from veryLargeTable Order By VLTID) A order by VLTID desc) Y On Z.VLTID = Y.VLTID order By Z.VLTID'
exec(@.execStr)
go

</code>

|||JB, thanks for writing the above - I intend to play with what you'vewritten. Before I do I want to modify the original justinproduced, to take in a PageIndex rather than a start row. I amnot so good at SQL, and tried the following:
CREATE PROCEDURE [dbo].[PagingQueryProductsByCategory]
(
@.CategoryId int = 0,
@.PageIndex int = 1,
@.RowCount int = 10,
@.TotalRowCount int OUTPUT
)
AS
Declare @.TotalRows int, @.StartPosition int
Declare @.PK int
DECLARE @.tmpTable TABLE (
PK int NOT NULL PRIMARY KEY
)
Set RowCount @.RowCount
SELECT @.StartPosition = (((@.PageIndex - 1) * @.RowCount) + 1)
DECLARE PagingCursor CURSOR DYNAMIC READ_ONLY FOR
select a.ProductId
from
products a,
categoryProducts b
where
b.categoryid = @.CategoryID and
b.productid = a.productid
Order By a.productid
Open PagingCursor
Fetch Relative @.StartPosition From PagingCursor Into @.PK
while (@.RowCount <> 0) And (@.@.Fetch_Status = 0)
begin
Insert Into @.tmpTable (PK)
Values (@.PK)
Fetch Next From PagingCursor Into @.PK
Set @.RowCount = @.RowCount - 1
end
Close PagingCursor
Deallocate PagingCursor
Select Products.* From Products
Join @.tmpTable temp ON Products.ProductID = temp.PK
Order By Products.ProductID
Set RowCount 0
GO
If I execute it with PageIndex = 1, I get back say 10 rows. If Iexecute it with PageIndex > 1, I get nothing returned. I thinkit could be to do with the way the curso works with the Relativekeyword - I dont know how cursors work. Any advice?
Thanks.
JR.
|||

<code>
--## Make sure this query returns a LARGE resultset of ProductID's
select a.ProductId
from
products a,
categoryProducts b
where
b.categoryid = @.CategoryID and
b.productid = a.productid
Order By a.productid

-## If it doesn't tweek it until it does.


--## NEXT Ceate THIS procedure
CREATE PROCEDURE dbo.TestVeryLargePaging_Fast

@.Page int,
@.RecsPerPage int,
@.TotalPages int OUTPUT

AS

DECLARE @.FirstRec int
SELECT @.FirstRec = (@.Page -1) * @.RecsPerPage + 1

DECLARE @.RowCount int
SELECT @.RowCount = @.RecsPerPage

SELECT @.TotalPages = ( SELECT COUNT(*)/@.RecsPerPage + 1 FROM VeryLargeTable )

DECLARE @.PK int
DECLARE @.tmpTable TABLE (
PK int NOT NULL PRIMARY KEY
)

DECLARE PagingCursor CURSOR DYNAMIC READ_ONLY FOR

--## REPLACE THIS WITH YOUR RESLUT SET FROM ABOVE IF NEEDED
select a.ProductId
from
products a,
categoryProducts b
where
b.categoryid = @.CategoryID and
b.productid = a.productid
Order By a.productid


OPEN PagingCursor
FETCH RELATIVE @.FirstRec FROM PagingCursor INTO @.PK

WHILE (@.RowCount <> 0) And (@.@.Fetch_Status = 0)
BEGIN
INSERT INTO @.tmpTable (PK)
VALUES (@.PK)

FETCH NEXT FROM PagingCursor INTO @.PK
SET @.RowCount = @.RowCount - 1
END

CLOSE PagingCursor
DEALLOCATE PagingCursor


Select Products.* From Products p
Join @.tmpTable temp ON p.ProductID = temp.PK
Order By Products.ProductID

GO


--## The above procedure take 3 parameters.
--## @.Page -- This is the page number -- 1st, 2nd, third etc...set it to 1, or 2, or 3 etc...
--## @.RecsPerPage -- This is the number of results perpage that you want returned. Set it to 25 or 50 or 10 etc...
--## @.TotalPages -- This is an output parameter that tell you how many pages there are bases on the settings of @.Page and PRecsPerPage.


--## TO EXECUTE THE PROCEDURE RUN THIS AND PUT YOUR PARAMETERS IN ORDER
DECLARE @.Total int
EXEC dbo.TestVeryLargePaging_Fast 2, 50, @.Total OUTPUT
PRINT 'Total Pages: ' + CAST(@.Total as varchar(50))

GO

</code>

|||

JRieggle wrote:


I think it could be to do with the way the curso works with the Relative keyword - I dont know how cursors work. Any advice?


Cursors forces a database to keep data in one order instead of the Rows and Columns of the relational model, a Cursor with more than three FETCH can confuse SQL Server query processor, as Peter Gulutzan who tested and watched said you have asked me to do something I am not equipped to do so you think I need five loops but I am going to take twenty loops. But paging is not easy to create. Hope this helps.

|||

JBelthoff wrote:

A little help fromhttp://www.seventhnight.com/ and now it is screamin fast!
<code>
ALTER PROCEDURE dbo.TestVeryLargePaging_Fast_New

@.Page int,
@.RecsPerPage int,
@.TotalPages int OUTPUT

as

SELECT @.TotalPages = ( SELECT COUNT(*)/@.RecsPerPage + 1 FROM VeryLargeTable )

Declare @.execStr varchar(2000)

Set @.execStr = 'Select Z.* From veryLargeTable Z Inner Join (Select top ' + convert(varchar,@.RecsPerPage) +
' VLTID from (Select top ' + convert(varchar,@.RecsPerPage*(@.page)) +
'VLTID from veryLargeTable Order By VLTID) A order by VLTID desc) Y OnZ.VLTID = Y.VLTID order By Z.VLTID'
exec(@.execStr)
go

</code>


Hmm... alright! I must just test it out with some unit tests and that tonight.
The only thing that I'm a bit doubtful about "standard paging" withSeventhnight's solution is with sorting. It is generally an expensiveoperation but the real question is whose is the most expensive of themall?Smile [:)] Other than talking in terms of raw speed, there is onefeature you sacrifice if you go with his solution is that you can'thave dynamic sorting (ie: you would like to be able to sort on itemsfrom the datagrid columns).
|||I have a question regarding sorting and reallife applications. Lets say I want to browse a certain product category, and I want tooffer a number of different sorting orders (A-Z, Z-A, Price High-Low,Price Low-High, etc...like Amazon). Based on the scripts in thismessage thread, where would the ordering come in? I am trying to workout if building the SQL in the business layer will be any better thanbuilding it in a stored procedure? If building in a stored procedure,how would it be possible to support all of these different routines?
Thanks for any ideas
jr.
|||

<code>
CREATE PROCEDURE dbo.TestVeryLargePaging_Fast_New

@.Page int,
@.RecsPerPage int,
@.OrderCoumn varchar(100),
@.TotalPages int OUTPUT

as

SELECT @.TotalPages = ( SELECT COUNT(*)/@.RecsPerPage + 1 FROM VeryLargeTable )

Declare @.execStr varchar(2000)

Set @.execStr = 'Select Z.* From veryLargeTable Z Inner Join (Select top ' + convert(varchar,@.RecsPerPage) +
' VLTID from (Select top ' + convert(varchar,@.RecsPerPage*(@.page)) +
' VLTID from veryLargeTable Order By VLTID) A order by VLTID desc) Y On Z.VLTID = Y.VLTID order By ' + @.OrderCoumn
exec(@.execStr)
go


</code>

|||JB,
Just writing to ask some questions about your SQL. I rewrote it to make it easier to read:
Select Z.* From Products Z Inner Join
(Select top 20 A.ProductID
from (
Select top 20 B1.ProductID
from Products B1, categoryProducts B2
where B2.CategoryID = 1 and B1.ProductID = B2.ProductID
Order By B1.Name
) A
order by A.Name desc
) Y On Z.ProductID = Y.ProductID
order by Z.Name
Lets say the blue is the core search. In this search the Order Byuses the Name, rather than the Id. The reason I am doing thishere, is because if I use the query as it was in your previous post,indexing to a particular page, I noticed only the results in that pageare ordered, which isnt what I want. I want to order the completeset, then page. This is why I moved the Order into thecore. This then produces a table of n results. The top 20 would have been top 10 * PageIndex which is set to 2, but Icouldnt get it to work for this example, and substituted it for thepage index. This inner query will create a resultset PageIndex *RowCount long. If the result count is only 20, and the pageindexis 10, then the number of results created in the core query will be200. The outer query in green confuses me, because I dont knowwhy the order by clause is there. It seems to me that all thatneeds to be done is take the top 20 off of the inner query resultlist. However, I see the reason for the order by is to invert thelist, since the page we want is at the end, and this ordering invertsthe complete resultset. Originally this query was orderingcompletely on the ProductID until the veryu outer query (Z.ProductID isnow changed to Z.Name).
One concern I have with this query is that I need to order the itemsagain on the very outer query - is this because the indexer will matchthe IDs by going down the ProductID key field, which will be in order?If I dont have the order by Z.Name, the items come out in ProductIDorder. My last point was to say the reason I posted this is tokeep along with this thread, a version of the query that uses adifferent column to sort by.
Thanks JB,
jr.

Paging with Stored Procedures

I have been browsing the newsgroups trying to find a good solution for this
problem.
I have a resultset and I need to show that information in pages. I also need
to have this sorted by a specific column (Date for example)
I found the following solution written by Don Arsenault that works very
well:
/*
The above routines assume that the resultset is ordered by the unique key.
If that's not true, a combination of a sort column and the unique key
can be used. Pass the sort column value as well as the unique key to the
next_page and previous_page procedures. Make sure the table has an index
on the combination of the sort column and the unqiue key.
*/
CREATE PROCEDURE next_page
@.current_page_last_row_key int,
@.current_page_last_row_sort int
AS
--return first page if parameters are null.
IF (@.current_page_last_row_key is null)
SELECT TOP 10 *
FROM my_big_table
ORDER BY sort_column, unique_key
ELSE
SELECT TOP 10 *
FROM my_big_table
WHERE
(sort_column >= @.current_page_last_row_sort)
and (
(sort_column > @.current_page_last_row_sort)
or (unique_key > @.current_page_last_row_key)
)
ORDER BY sort_column, unique_key
CREATE PROCEDURE previous_page
@.current_page_first_row_key int,
@.current_page_first_row_sort int
AS
--return last page if parameters are null.
IF (@.current_page_first_row_sort_key is null)
SELECT *
FROM
(
SELECT TOP 10 *
FROM my_big_table
ORDER BY sort_column DESC, unique_key DESC
) AS Reorder
ORDER BY unique_key
ELSE
SELECT *
FROM
(
SELECT TOP 10 *
FROM my_big_table
WHERE
(sort_column <= @.current_page_last_row_sort)
and (
(sort_column < @.current_page_last_row_sort)
or (unique_key < @.current_page_last_row_key)
)
ORDER BY sort_column DESC, unique_key DESC
) AS Reorder
ORDER BY sort_column, unique_key
That works great when you want to move from one page to the next (or to the
previous one), but I don't know
how I can go to a specific page. For example, go to page 100.
Do you guys know how I can get this?
ThanksYou may also want to refer to www.aspfaq.com/2120 for some ideas.
Anith

Paging with Gridview and ObjectDataSource

I have a problem with efficiently paging with gridview and objectdatasoruce. I have GetPosts1(startRowIndex, maximumRow, topic_id) and GetPostsCount(topic_id). I tested each procedure and each are working correctly. The problem is with the controls. Here is the code for the controls.

<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AutoGenerateColumns="False" DataKeyNames
DataSourceID="ObjectDataSource2">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="RowNumber" SortExpression="RowNumber" />
<asp:BoundField DataField="post_id" HeaderText="post_id" SortExpression="post_id" />
<asp:BoundField DataField="post_subject" HeaderText="post_subject" SortExpression="post_subject" />
<asp:BoundField DataField="post_text" HeaderText="post_text" SortExpression="post_text" />
<asp:BoundField DataField="post_time" HeaderText="post_time" SortExpression="post_time" />
<asp:BoundField DataField="topic_id" HeaderText="topic_id" SortExpression="topic_id" />
<asp:BoundField DataField="UserName" HeaderText="UserName" SortExpression="UserName" />
<asp:BoundField DataField="UserID" HeaderText="UserID" SortExpression="UserID" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ObjectDataSource2" runat="server" OldValuesParameterFormatString="original_{0}"
EnablePaging="True" SelectMethod="GetPosts1" SelectCountMethod="GetPostsCount" TypeName="PostsTableAdapters.discussions_GetPostsTableAdapter">
<SelectParameters>
<asp:QueryStringParameter DefaultValue="48" Name="topic_id" QueryStringField="t" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>

When I run the page, I get "A first chance exception of type 'System.InvalidOperationException' occurred in System.Data.dll" and then "The thread '<No Name>' (0xbe0) has exited with code 0 (0x0)."

Could the problem be with null or empty values in the returned data?

Here is an example which work:

<asp:ObjectDataSourceID="odsObjectDataSource"runat="server"SelectMethod="GetResults"TypeName="ResultsList">

<SelectParameters>

<asp:ParameterDefaultValue="0"Name="StartRow"Type="Int32"/>

<asp:SessionParameterName="xslSearch"SessionField="xsltPathShowRezults"Type="String"/>

</SelectParameters>

</asp:ObjectDataSource>

Monday, March 12, 2012

Paging with Gridview and ObjectDataSource

I'm trying to effecinty page through many rows of data with the gridview and objectdatasource. I'm having trouble. I'm using a table adapter with predefined counting and select methods. I have tested all the methods and they all work properly. But when I configure the object datasource to use the table adapter, and set the gridviews datasrouce, the page doesn't load and I wind up getting "time out". Any help?

<asp:GridView ID="GridView1" runat="server" AllowPaging="True" DataSourceID="objTopics">
<Columns>
<asp:BoundField DataField="topic_title" />
</Columns>
<EmptyDataTemplate>
<p>NOTHING HERE</p>
</EmptyDataTemplate>
</asp:GridView>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" EnablePaging="True" OldValuesParameterFormatString="original_{0}"
SelectMethod="GetTopics" SelectCountMethod="GetTopicsRowCount" TypeName="TopicsTableAdapters.discussions_GetTopicsSubSetTableAdapter">
<SelectParameters>
<asp:Parameter DefaultValue="1" Name="startRowIndex" Type="Int32" />
<asp:Parameter DefaultValue="10" Name="maximumRows" Type="Int32" />
<asp:Parameter DefaultValue="1" Name="board_id" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>

<asp:GridViewID="gvResult"

runat="server"AutoGenerateColumns="False"CssClass="dataGrid"

OnSelectedIndexChanged="GridView1_SelectedIndexChanged"OnRowDataBound="gvResult_RowDataBound"AllowPaging="True"AllowSorting="True"DataSourceID="odsObjectDataSource"OnPageIndexChanged="gvResult_PageIndexChanged"PageSize="5">

<Columns>

<asp:ButtonFieldCommandName="Select"HeaderText="Select"Text="<img src='../IMAGES/select.jpg'/>"/>

<asp:BoundFieldDataField="SocieteId"HeaderText="Identifiant"ReadOnly="True"/>

<asp:BoundFieldDataField="SocieteLocalite"HeaderText="Localité"ReadOnly="True"/>

</Columns>

<AlternatingRowStyleCssClass="alt"/>

<PagerSettingsMode="NextPreviousFirstLast"/>

</asp:GridView>

<asp:LabelID="lblError"runat="server"Text=""></asp:Label></div>

<asp:ObjectDataSourceID="odsObjectDataSource"runat="server"SelectMethod="GetResults"TypeName="ResultsList">

<SelectParameters>

<asp:ParameterDefaultValue="0"Name="StartRow"Type="Int32"/>

<asp:SessionParameterName="xslSearch"SessionField="xsltPathShowRezults"Type="String"/>

</SelectParameters>

</asp:ObjectDataSource>

For the object datasource you have to writye a class wich will get data, like

privateDataView GetData(int StartRow,string xslSearch)

{

//your code here

return PagedResultsTable.DefaultView;

}

and this method is set in the design for the object datasource.

Paging when PDF is rendered

I have report that generates a person's resume. The resume sections
(experience, education, skills ...) do not page correctly when exported to
PDF or TIFF. Instead of keeping sections together on the same page the
sections is moved to the next page even though there is sufficient space left
at the bottom of the current page.
I would really appreciate any help since this is due next week.Hi Adil,
Did you solve this issue?.
I'm also got stuck with the same problem.
Please help if you have solved this issue.
Thanks,
Ranjith
"Adil" wrote:
> I have report that generates a person's resume. The resume sections
> (experience, education, skills ...) do not page correctly when exported to
> PDF or TIFF. Instead of keeping sections together on the same page the
> sections is moved to the next page even though there is sufficient space left
> at the bottom of the current page.
> I would really appreciate any help since this is due next week.
>|||No solution yet. I was hoping someone from Microsoft could look at this...|||I have the same problem.
Data groups are being put on new pages instead of flowing. "KeepTogether"
property for all data regions is set to "False" but the groups are still
moved to new pages.
In design preview mode the data layout is perfect - until I print preview
or export to pdf - extra pages get added.
I installed SP2 and that solved another problem that I had - the first page
was blank in print preview mode but this problem still persists.
Anyway - sorry I can't help you on this one but I am hoping MS knows that
more than one person is having this problem.
Cheers
"Adil" <Adil@.discussions.microsoft.com> wrote in message
news:8919C1C9-7E48-4A0D-A24A-D8CADD772DFE@.microsoft.com...
> No solution yet. I was hoping someone from Microsoft could look at this...|||Hi,
I got to know that, this behaviour is as per the design. When we have list,
they implicitly set Keep together property to true during the rendering time.
The workaround given by microsoft is to use "Tables" instead of "list" in
the reports.
I believe microsoft people will help us for sure to fix this issue,else we
have no other option to redesign the reports from the scratch using tables
instead of list.
Thanks,
Ranjith
"Tim Powers" wrote:
> I have the same problem.
> Data groups are being put on new pages instead of flowing. "KeepTogether"
> property for all data regions is set to "False" but the groups are still
> moved to new pages.
> In design preview mode the data layout is perfect - until I print preview
> or export to pdf - extra pages get added.
> I installed SP2 and that solved another problem that I had - the first page
> was blank in print preview mode but this problem still persists.
> Anyway - sorry I can't help you on this one but I am hoping MS knows that
> more than one person is having this problem.
> Cheers
>
>
> "Adil" <Adil@.discussions.microsoft.com> wrote in message
> news:8919C1C9-7E48-4A0D-A24A-D8CADD772DFE@.microsoft.com...
> > No solution yet. I was hoping someone from Microsoft could look at this...
>
>|||Thanks - tables work!
I originally used the wizard and to create a group -- the wizard uses lists,
not tables.
Anyway this issue caused me 2 days of work - I couldn't find any
information to solve this problem.
Thanks for the tip!
"Ranjith Prakash" <RanjithPrakash@.discussions.microsoft.com> wrote in
message news:89D8F795-E366-4B74-BB96-BEDC4370809A@.microsoft.com...
> Hi,
> I got to know that, this behaviour is as per the design. When we have
list,
> they implicitly set Keep together property to true during the rendering
time.
> The workaround given by microsoft is to use "Tables" instead of "list" in
> the reports.
> I believe microsoft people will help us for sure to fix this issue,else we
> have no other option to redesign the reports from the scratch using tables
> instead of list.
> Thanks,
> Ranjith
> "Tim Powers" wrote:
> > I have the same problem.
> >
> > Data groups are being put on new pages instead of flowing.
"KeepTogether"
> > property for all data regions is set to "False" but the groups are still
> > moved to new pages.
> >
> > In design preview mode the data layout is perfect - until I print
preview
> > or export to pdf - extra pages get added.
> >
> > I installed SP2 and that solved another problem that I had - the first
page
> > was blank in print preview mode but this problem still persists.
> >
> > Anyway - sorry I can't help you on this one but I am hoping MS knows
that
> > more than one person is having this problem.
> >
> > Cheers
> >
> >
> >
> >
> > "Adil" <Adil@.discussions.microsoft.com> wrote in message
> > news:8919C1C9-7E48-4A0D-A24A-D8CADD772DFE@.microsoft.com...
> > > No solution yet. I was hoping someone from Microsoft could look at
this...
> >
> >
> >

paging w/ sql server 2k

hi, whats the best way to get say results from 41 to 60 from a query?
thankshttp://www.aspfaq.com/2120
"Fred" <fred@.ilovespam.com> wrote in message
news:uFpRfkdJGHA.216@.TK2MSFTNGP15.phx.gbl...
> hi, whats the best way to get say results from 41 to 60 from a query?
> thanks

Paging using Web Services

We are developing a Web Application for which we have written a class to
render reports that consumes web services provided by Reporting Services.
We invoke "Render" method of web service for displaying report in aspx page.
Paging is achieved using "Section" config of HTMLDeviceInfo passed to render
method.
This approach is working fine for First Page, Previous Page and Next Page
buttons. However we are not able to implement code for Last Page Button
because we are unable to retrieve details regarding total number of pages
through code.
Documentation states that if a value greater than last page index is passed
to "Section" config then Web Service would render last page. This behavior is
causing our code to crash.
Any idea how to overcome this problem.
Thanks in advance.I've described my approach a few months ago.
http://groups.google.com/group/microsoft.public.sqlserver.reportingsvcs/tree/browse_frm/thread/5a73412801f5ba54/f63ce6b85e448735?rnum=1&hl=en&q=%22Oleg+Yevteyev%22+pages&_done=%2Fgroup%2Fmicrosoft.public.sqlserver.reportingsvcs%2Fbrowse_frm%2Fthread%2F5a73412801f5ba54%2F41e4ed35916811eb%3Flnk%3Dst%26q%3D%22Oleg+Yevteyev%22+pages%26rnum%3D8%26hl%3Den%26#doc_ac075ac1383673e8
Hope that helps
Oleg Yevteyev,
San Diego, CA
It is OK to contact me with a contracting opportunity.
"myfirstname"001atgmaildotcom.
Replace "myfirstname" with Oleg.
--
"PVV" <PVV@.discussions.microsoft.com> wrote in message
news:327535A8-2C87-4B38-A60D-223B95D8AFD2@.microsoft.com...
> We are developing a Web Application for which we have written a class to
> render reports that consumes web services provided by Reporting Services.
> We invoke "Render" method of web service for displaying report in aspx
> page.
> Paging is achieved using "Section" config of HTMLDeviceInfo passed to
> render
> method.
> This approach is working fine for First Page, Previous Page and Next Page
> buttons. However we are not able to implement code for Last Page Button
> because we are unable to retrieve details regarding total number of pages
> through code.
> Documentation states that if a value greater than last page index is
> passed
> to "Section" config then Web Service would render last page. This behavior
> is
> causing our code to crash.
> Any idea how to overcome this problem.
> Thanks in advance.
>

Paging using Web Service

To get the UI we required, we built a custom .NET front end that
communicates directly with the MSRS web service. Paging (e.g. a break in the
data at a certain point with some indicator for the "next" page) does not
seem to work once you take this approach. Anyone figured this out?Hi Sean,
> To get the UI we required, we built a custom .NET front end that
> communicates directly with the MSRS web service. Paging (e.g. a break in the
[...]
>does not seem to work once
What doesn't work?
I used the same approch. My user control calls RS webservice with parameter "Section" of device settings so I can _read_ report section by section.
There is only a little problem... there is no way... perhaps is better to say I don't find any way to known How many sections I must paging :o
HTH M.rkino
--
Marco Barzaghi - [MVP - MCP]
http://mvp.support.microsoft.com - http://italy.mvps.org
UGIDotNet - User Group Italiano .NET, http://www.ugidotnet.org
Read my WebLog: http://www.ugidotnet.org/436.blog

Paging Technique

Questoin

I am using Sql Server 2000.

I have a table named Cities which has more than 2600000 records.

I have to display the records for a specific city page wise.

I don't want to compromise with performance.

Can anyone has the idea?

Waiting for your fruitful response.

Happy Day And Night For All

Muhammad Zeeshanuddin Khan

Hi Muhammad,

Check out this article. The idea behind is that you only fetch the records from the database that you display on the active pageIndex.

Succes!

Rutger van Hagen

Paging Reports

Hi All

I created a report with a matrix on the form and managed to get the results "not" to page when viewed on the web by selecting the "Fit matrix to one page if possible" checkbox.

I created a new report looking at the same data this time using a table and no matter what i do the report keeps paging!!!

Anyone got any advice on how to stop this? Why does it handle a table differently than a table.

Thanks very much

KeepTogether is not currently supported in interactive renderers (HTML and preview). You can try changing the InteractiveHeight property on the report to 0 in order to get the entire report on one page.|||

Setting the Interactive Height to 0in did the trick

aka

<InteractiveHeight>0in</InteractiveHeight>

Cheers

Paging records on SQL server using derived tables : more question

I did use query plans to find out more. ( Please see the thread BELOW)
I have a question on this, if someone can help me with that it will be
great.
In my SQL query that selects data from table, I have a where clause
which states :
where PermitID like @.WorkType
order by WorkStart DESC
@.WorkType is a input parameter to the Stored proc and its value is
'01%'
When I use the above where clause, all the Sorts in the ESTIMATED Query
Execution plan show me a COST of 28%.
However if I change the query manually to say:
where PermitID like '01%'
order by WorkStart DESC
The COST of the Sort (in ESTIMATED Query Execution plan) reduces to 2%
and at the beginning of the PLAN, there is a Bookmark Lookup which
includes the above where clause.
Whereas with the FIRST example , the BookMark Lookup in the beginning
doesn't show that where condition.
Can anyone help me better understand this anomaly?
TIA
===================================== I am using derived tables to Page data on the SQL Server side.
I used this link as my mentor for doing paging on the SQL
Server
http://msdn2.microsoft.com/en-us/library/ms979197.aspx
I wanted to use USER PAGING, thus I used the following code:
CREATE PROCEDURE UserPaging
(
@.currentPage int = 1, @.pageSize int =1000
)
AS
DECLARE @.Out int, @.rowsToRetrieve int, @.SQLSTRING nvarchar(1000)
SET @.rowsToRetrieve = (@.pageSize * @.currentPage)
SET NOCOUNT ON
SET @.SQLSTRING = N'select
CustomerID,CompanyName,ContactName,ContactTitle from
( SELECT TOP '+ CAST(@.pageSize as varchar(10)) +
'CustomerId,CompanyName,ContactName,ContactTitle from
( SELECT TOP ' + CAST(@.rowsToRetrieve as varchar(10)) +
'CustomerID,CompanyName,ContactName,ContactTitle FROM
( SELECT TOP ' + CAST(@.rowsToRetrieve as varchar(10)) +
'CustomerID,CompanyName,ContactName,ContactTitle FROM Customers as T1
ORDER BY contactname) AS T2 ORDER BY contactname DESC ) AS T3)
As T4 ORDER BY contactname ASC'
EXEC(@.SQLSTRING)
RETURN
GO
When I use this. Assume that the Total records returned by the SQL
query is 1198.Thus when I am on Page1 the above Stored Proc (SP) will
return the first 1000 records.
This works absolutely fine.
Now I am on Page2, now I need to retrieve only the remaining 198
records.But if I use the above SP, it will return the last 1000
records.So to tweak this I used the following logic to set the
@.pagesize variable:
Declare @.PageCount int
select @.PageCount = @.TotalRows/@.PageSize
if @.currentPage > @.PageCount SET @.PageSize = @.TotalRows%@.PageSize
Since I am on Page2 the above logic will set the PageSize to 198 and
not 1000.But when I use this logic, it takes forever for the SP to
return the 198 records in a resultset.
However if the TotalRows were = 1800, and thus the PageSize=800 or
greater, this SP returns the resultset quickly enough.
Thus to get over this problem I had to use the other logic i.e. using
Application Paging (i.e. first storing the entire result set into a
Temp table, then retrieving only the required records for the PAGE)
Can anyone suggest what is wrong with my user paging logic'?
TIA...rbg (rbg.net@.gmail.com) writes:
> I have a question on this, if someone can help me with that it will be
> great.
> In my SQL query that selects data from table, I have a where clause
> which states :
> where PermitID like @.WorkType
> order by WorkStart DESC
> @.WorkType is a input parameter to the Stored proc and its value is
> '01%'
> When I use the above where clause, all the Sorts in the ESTIMATED Query
> Execution plan show me a COST of 28%.
> However if I change the query manually to say:
> where PermitID like '01%'
> order by WorkStart DESC
> The COST of the Sort (in ESTIMATED Query Execution plan) reduces to 2%
> and at the beginning of the PLAN, there is a Bookmark Lookup which
> includes the above where clause.
> Whereas with the FIRST example , the BookMark Lookup in the beginning
> doesn't show that where condition.
> Can anyone help me better understand this anomaly?
That WHERE clause was not in your original post. Nor does the column
name seem entirely familiar. I gather that what you posted yesterday
was a sample from an MSDN article, but it can be tricky to give accurate
answers, ir you don't post your actual code.
But some optimizer bascis: when SQL Server builds the query plan
for a stored procedure, it builds the plan for the procedure as a
whole. This means that it does not know what values that variables
will have at time for execution. The same applies to parameters, but
in this case it does at least know the input value, and uses this
value as guidance. (This is known as parameter sbiffing.)
But SQL Server does not build a query plan every time a procedure
is executed. Instead the plan is put in cache, and the cached plan
will be reused - even if the procedure is called with input values
for which the cached plan is no good.
In your case, assume the the procedure was first called with
WorkType '%01'. For this input value any index on PermitID is not
very useful, so most likely you will get a table scan instead.
On the other hand, when you hardcode a value. SQL Server have full
information, and the odds for a good plan are much better.
To test this theory, you can say:
EXEC your_sp @.WorkTyoe WITH RECOMPILE
if you get a berrer plan, the problem was that you had a plan created
for a differnt value in the cache.
--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx|||rbg,
SqlServerCentral.com has an article on paging. You will need to sign up to
get access.
http://www.sqlteam.com/item.asp?ItemID=26455
-- Bill
"rbg" <rbg.net@.gmail.com> wrote in message
news:1169732779.351525.299580@.s48g2000cws.googlegroups.com...
>I did use query plans to find out more. ( Please see the thread BELOW)
> I have a question on this, if someone can help me with that it will be
> great.
> In my SQL query that selects data from table, I have a where clause
> which states :
> where PermitID like @.WorkType
> order by WorkStart DESC
> @.WorkType is a input parameter to the Stored proc and its value is
> '01%'
> When I use the above where clause, all the Sorts in the ESTIMATED Query
> Execution plan show me a COST of 28%.
> However if I change the query manually to say:
> where PermitID like '01%'
> order by WorkStart DESC
> The COST of the Sort (in ESTIMATED Query Execution plan) reduces to 2%
> and at the beginning of the PLAN, there is a Bookmark Lookup which
> includes the above where clause.
> Whereas with the FIRST example , the BookMark Lookup in the beginning
> doesn't show that where condition.
> Can anyone help me better understand this anomaly?
> TIA
> =====================================> I am using derived tables to Page data on the SQL Server side.
> I used this link as my mentor for doing paging on the SQL
> Server
> http://msdn2.microsoft.com/en-us/library/ms979197.aspx
> I wanted to use USER PAGING, thus I used the following code:
> CREATE PROCEDURE UserPaging
> (
> @.currentPage int = 1, @.pageSize int =1000
> )
> AS
> DECLARE @.Out int, @.rowsToRetrieve int, @.SQLSTRING nvarchar(1000)
> SET @.rowsToRetrieve = (@.pageSize * @.currentPage)
> SET NOCOUNT ON
> SET @.SQLSTRING = N'select
> CustomerID,CompanyName,ContactName,ContactTitle from
> ( SELECT TOP '+ CAST(@.pageSize as varchar(10)) +
> 'CustomerId,CompanyName,ContactName,ContactTitle from
> ( SELECT TOP ' + CAST(@.rowsToRetrieve as varchar(10)) +
> 'CustomerID,CompanyName,ContactName,ContactTitle FROM
> ( SELECT TOP ' + CAST(@.rowsToRetrieve as varchar(10)) +
> 'CustomerID,CompanyName,ContactName,ContactTitle FROM Customers as T1
> ORDER BY contactname) AS T2 ORDER BY contactname DESC ) AS T3)
> As T4 ORDER BY contactname ASC'
> EXEC(@.SQLSTRING)
> RETURN
> GO
> When I use this. Assume that the Total records returned by the SQL
> query is 1198.Thus when I am on Page1 the above Stored Proc (SP) will
> return the first 1000 records.
> This works absolutely fine.
> Now I am on Page2, now I need to retrieve only the remaining 198
> records.But if I use the above SP, it will return the last 1000
> records.So to tweak this I used the following logic to set the
> @.pagesize variable:
> Declare @.PageCount int
> select @.PageCount = @.TotalRows/@.PageSize
> if @.currentPage > @.PageCount SET @.PageSize = @.TotalRows%@.PageSize
> Since I am on Page2 the above logic will set the PageSize to 198 and
> not 1000.But when I use this logic, it takes forever for the SP to
> return the 198 records in a resultset.
> However if the TotalRows were = 1800, and thus the PageSize=800 or
> greater, this SP returns the resultset quickly enough.
> Thus to get over this problem I had to use the other logic i.e. using
> Application Paging (i.e. first storing the entire result set into a
> Temp table, then retrieving only the required records for the PAGE)
> Can anyone suggest what is wrong with my user paging logic'?
> TIA...
>

Paging records on SQL server using derived tables : more question

I did use query plans to find out more. ( Please see the thread BELOW)
I have a question on this, if someone can help me with that it will be
great.
In my SQL query that selects data from table, I have a where clause
which states :
where PermitID like @.WorkType
order by WorkStart DESC
@.WorkType is a input parameter to the Stored proc and its value is
'01%'
When I use the above where clause, all the Sorts in the ESTIMATED Query
Execution plan show me a COST of 28%.
However if I change the query manually to say:
where PermitID like '01%'
order by WorkStart DESC
The COST of the Sort (in ESTIMATED Query Execution plan) reduces to 2%
and at the beginning of the PLAN, there is a Bookmark Lookup which
includes the above where clause.
Whereas with the FIRST example , the BookMark Lookup in the beginning
doesn't show that where condition.
Can anyone help me better understand this anomaly?
TIA
=====================================
I am using derived tables to Page data on the SQL Server side.
I used this link as my mentor for doing paging on the SQL
Server
http://msdn2.microsoft.com/en-us/library/ms979197.aspx
I wanted to use USER PAGING, thus I used the following code:
CREATE PROCEDURE UserPaging
(
@.currentPage int = 1, @.pageSize int =1000
)
AS
DECLARE @.Out int, @.rowsToRetrieve int, @.SQLSTRING nvarchar(1000)
SET @.rowsToRetrieve = (@.pageSize * @.currentPage)
SET NOCOUNT ON
SET @.SQLSTRING = N'select
CustomerID,CompanyName,ContactName,Conta
ctTitle from
( SELECT TOP '+ CAST(@.pageSize as varchar(10)) +
'CustomerId,CompanyName,ContactName,Cont
actTitle from
( SELECT TOP ' + CAST(@.rowsToRetrieve as varchar(10)) +
'CustomerID,CompanyName,ContactName,Cont
actTitle FROM
( SELECT TOP ' + CAST(@.rowsToRetrieve as varchar(10)) +
'CustomerID,CompanyName,ContactName,Cont
actTitle FROM Customers as T1
ORDER BY contactname) AS T2 ORDER BY contactname DESC ) AS T3)
As T4 ORDER BY contactname ASC'
EXEC(@.SQLSTRING)
RETURN
GO
When I use this. Assume that the Total records returned by the SQL
query is 1198.Thus when I am on Page1 the above Stored Proc (SP) will
return the first 1000 records.
This works absolutely fine.
Now I am on Page2, now I need to retrieve only the remaining 198
records.But if I use the above SP, it will return the last 1000
records.So to tweak this I used the following logic to set the
@.pagesize variable:
Declare @.PageCount int
select @.PageCount = @.TotalRows/@.PageSize
if @.currentPage > @.PageCount SET @.PageSize = @.TotalRows%@.PageSize
Since I am on Page2 the above logic will set the PageSize to 198 and
not 1000.But when I use this logic, it takes forever for the SP to
return the 198 records in a resultset.
However if the TotalRows were = 1800, and thus the PageSize=800 or
greater, this SP returns the resultset quickly enough.
Thus to get over this problem I had to use the other logic i.e. using
Application Paging (i.e. first storing the entire result set into a
Temp table, then retrieving only the required records for the PAGE)
Can anyone suggest what is wrong with my user paging logic'?
TIA...rbg (rbg.net@.gmail.com) writes:
> I have a question on this, if someone can help me with that it will be
> great.
> In my SQL query that selects data from table, I have a where clause
> which states :
> where PermitID like @.WorkType
> order by WorkStart DESC
> @.WorkType is a input parameter to the Stored proc and its value is
> '01%'
> When I use the above where clause, all the Sorts in the ESTIMATED Query
> Execution plan show me a COST of 28%.
> However if I change the query manually to say:
> where PermitID like '01%'
> order by WorkStart DESC
> The COST of the Sort (in ESTIMATED Query Execution plan) reduces to 2%
> and at the beginning of the PLAN, there is a Bookmark Lookup which
> includes the above where clause.
> Whereas with the FIRST example , the BookMark Lookup in the beginning
> doesn't show that where condition.
> Can anyone help me better understand this anomaly?
That WHERE clause was not in your original post. Nor does the column
name seem entirely familiar. I gather that what you posted yesterday
was a sample from an MSDN article, but it can be tricky to give accurate
answers, ir you don't post your actual code.
But some optimizer bascis: when SQL Server builds the query plan
for a stored procedure, it builds the plan for the procedure as a
whole. This means that it does not know what values that variables
will have at time for execution. The same applies to parameters, but
in this case it does at least know the input value, and uses this
value as guidance. (This is known as parameter sbiffing.)
But SQL Server does not build a query plan every time a procedure
is executed. Instead the plan is put in cache, and the cached plan
will be reused - even if the procedure is called with input values
for which the cached plan is no good.
In your case, assume the the procedure was first called with
WorkType '%01'. For this input value any index on PermitID is not
very useful, so most likely you will get a table scan instead.
On the other hand, when you hardcode a value. SQL Server have full
information, and the odds for a good plan are much better.
To test this theory, you can say:
EXEC your_sp @.WorkTyoe WITH RECOMPILE
if you get a berrer plan, the problem was that you had a plan created
for a differnt value in the cache.
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pr...oads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodin...ions/books.mspx|||rbg,
SqlServerCentral.com has an article on paging. You will need to sign up to
get access.
http://www.sqlteam.com/item.asp?ItemID=26455
-- Bill
"rbg" <rbg.net@.gmail.com> wrote in message
news:1169732779.351525.299580@.s48g2000cws.googlegroups.com...
>I did use query plans to find out more. ( Please see the thread BELOW)
> I have a question on this, if someone can help me with that it will be
> great.
> In my SQL query that selects data from table, I have a where clause
> which states :
> where PermitID like @.WorkType
> order by WorkStart DESC
> @.WorkType is a input parameter to the Stored proc and its value is
> '01%'
> When I use the above where clause, all the Sorts in the ESTIMATED Query
> Execution plan show me a COST of 28%.
> However if I change the query manually to say:
> where PermitID like '01%'
> order by WorkStart DESC
> The COST of the Sort (in ESTIMATED Query Execution plan) reduces to 2%
> and at the beginning of the PLAN, there is a Bookmark Lookup which
> includes the above where clause.
> Whereas with the FIRST example , the BookMark Lookup in the beginning
> doesn't show that where condition.
> Can anyone help me better understand this anomaly?
> TIA
> =====================================
> I am using derived tables to Page data on the SQL Server side.
> I used this link as my mentor for doing paging on the SQL
> Server
> http://msdn2.microsoft.com/en-us/library/ms979197.aspx
> I wanted to use USER PAGING, thus I used the following code:
> CREATE PROCEDURE UserPaging
> (
> @.currentPage int = 1, @.pageSize int =1000
> )
> AS
> DECLARE @.Out int, @.rowsToRetrieve int, @.SQLSTRING nvarchar(1000)
> SET @.rowsToRetrieve = (@.pageSize * @.currentPage)
> SET NOCOUNT ON
> SET @.SQLSTRING = N'select
> CustomerID,CompanyName,ContactName,Conta
ctTitle from
> ( SELECT TOP '+ CAST(@.pageSize as varchar(10)) +
> 'CustomerId,CompanyName,ContactName,Cont
actTitle from
> ( SELECT TOP ' + CAST(@.rowsToRetrieve as varchar(10)) +
> 'CustomerID,CompanyName,ContactName,Cont
actTitle FROM
> ( SELECT TOP ' + CAST(@.rowsToRetrieve as varchar(10)) +
> 'CustomerID,CompanyName,ContactName,Cont
actTitle FROM Customers as T1
> ORDER BY contactname) AS T2 ORDER BY contactname DESC ) AS T3)
> As T4 ORDER BY contactname ASC'
> EXEC(@.SQLSTRING)
> RETURN
> GO
> When I use this. Assume that the Total records returned by the SQL
> query is 1198.Thus when I am on Page1 the above Stored Proc (SP) will
> return the first 1000 records.
> This works absolutely fine.
> Now I am on Page2, now I need to retrieve only the remaining 198
> records.But if I use the above SP, it will return the last 1000
> records.So to tweak this I used the following logic to set the
> @.pagesize variable:
> Declare @.PageCount int
> select @.PageCount = @.TotalRows/@.PageSize
> if @.currentPage > @.PageCount SET @.PageSize = @.TotalRows%@.PageSize
> Since I am on Page2 the above logic will set the PageSize to 198 and
> not 1000.But when I use this logic, it takes forever for the SP to
> return the 198 records in a resultset.
> However if the TotalRows were = 1800, and thus the PageSize=800 or
> greater, this SP returns the resultset quickly enough.
> Thus to get over this problem I had to use the other logic i.e. using
> Application Paging (i.e. first storing the entire result set into a
> Temp table, then retrieving only the required records for the PAGE)
> Can anyone suggest what is wrong with my user paging logic'?
> TIA...
>

Paging records on SQL server using derived tables : more question

I did use query plans to find out more. ( Please see the thread BELOW)

I have a question on this, if someone can help me with that it will be
great.
In my SQL query that selects data from table, I have a where clause
which states :

where PermitID like @.WorkType
order by WorkStart DESC

@.WorkType is a input parameter to the Stored proc and its value is
'01%'

When I use the above where clause, all the Sorts in the ESTIMATED Query
Execution plan show me a COST of 28%.

However if I change the query manually to say:

where PermitID like '01%'
order by WorkStart DESC

The COST of the Sort (in ESTIMATED Query Execution plan) reduces to 2%
and at the beginning of the PLAN, there is a Bookmark Lookup which
includes the above where clause.
Whereas with the FIRST example , the BookMark Lookup in the beginning
doesn't show that where condition.

Can anyone help me better understand this anomaly?

TIA
=====================================
I am using derived tables to Page data on the SQL Server side.
I used this link as my mentor for doing paging on the SQL
Server

http://msdn2.microsoft.com/en-us/library/ms979197.aspx
I wanted to use USER PAGING, thus I used the following code:

CREATE PROCEDURE UserPaging
(
@.currentPage int = 1, @.pageSize int =1000
)
AS
DECLARE @.Out int, @.rowsToRetrieve int, @.SQLSTRING nvarchar(1000)

SET @.rowsToRetrieve = (@.pageSize * @.currentPage)

SET NOCOUNT ON
SET @.SQLSTRING = N'select
CustomerID,CompanyName,ContactName,ContactTitle from
( SELECT TOP '+ CAST(@.pageSize as varchar(10)) +
'CustomerId,CompanyName,ContactName,ContactTitle from
( SELECT TOP ' + CAST(@.rowsToRetrieve as varchar(10)) +
'CustomerID,CompanyName,ContactName,ContactTitle FROM
( SELECT TOP ' + CAST(@.rowsToRetrieve as varchar(10)) +
'CustomerID,CompanyName,ContactName,ContactTitle FROM Customers as T1
ORDER BY contactname) AS T2 ORDER BY contactname DESC ) AS T3)
As T4 ORDER BY contactname ASC'

EXEC(@.SQLSTRING)
RETURN
GO

When I use this. Assume that the Total records returned by the SQL
query is 1198.Thus when I am on Page1 the above Stored Proc (SP) will
return the first 1000 records.

This works absolutely fine.
Now I am on Page2, now I need to retrieve only the remaining 198
records.But if I use the above SP, it will return the last 1000
records.So to tweak this I used the following logic to set the

@.pagesize variable:
Declare @.PageCount int
select @.PageCount = @.TotalRows/@.PageSize
if @.currentPage @.PageCount SET @.PageSize = @.TotalRows%@.PageSize

Since I am on Page2 the above logic will set the PageSize to 198 and
not 1000.But when I use this logic, it takes forever for the SP to
return the 198 records in a resultset.
However if the TotalRows were = 1800, and thus the PageSize=800 or
greater, this SP returns the resultset quickly enough.

Thus to get over this problem I had to use the other logic i.e. using
Application Paging (i.e. first storing the entire result set into a
Temp table, then retrieving only the required records for the PAGE)

Can anyone suggest what is wrong with my user paging logic???
TIA...rbg (rbg.net@.gmail.com) writes:

Quote:

Originally Posted by

I have a question on this, if someone can help me with that it will be
great.
In my SQL query that selects data from table, I have a where clause
which states :
>
where PermitID like @.WorkType
order by WorkStart DESC
>
@.WorkType is a input parameter to the Stored proc and its value is
'01%'
>
When I use the above where clause, all the Sorts in the ESTIMATED Query
Execution plan show me a COST of 28%.
>
However if I change the query manually to say:
>
where PermitID like '01%'
order by WorkStart DESC
>
The COST of the Sort (in ESTIMATED Query Execution plan) reduces to 2%
and at the beginning of the PLAN, there is a Bookmark Lookup which
includes the above where clause.
Whereas with the FIRST example , the BookMark Lookup in the beginning
doesn't show that where condition.
>
Can anyone help me better understand this anomaly?


That WHERE clause was not in your original post. Nor does the column
name seem entirely familiar. I gather that what you posted yesterday
was a sample from an MSDN article, but it can be tricky to give accurate
answers, ir you don't post your actual code.

But some optimizer bascis: when SQL Server builds the query plan
for a stored procedure, it builds the plan for the procedure as a
whole. This means that it does not know what values that variables
will have at time for execution. The same applies to parameters, but
in this case it does at least know the input value, and uses this
value as guidance. (This is known as parameter sbiffing.)

But SQL Server does not build a query plan every time a procedure
is executed. Instead the plan is put in cache, and the cached plan
will be reused - even if the procedure is called with input values
for which the cached plan is no good.

In your case, assume the the procedure was first called with
WorkType '%01'. For this input value any index on PermitID is not
very useful, so most likely you will get a table scan instead.

On the other hand, when you hardcode a value. SQL Server have full
information, and the odds for a good plan are much better.

To test this theory, you can say:

EXEC your_sp @.WorkTyoe WITH RECOMPILE

if you get a berrer plan, the problem was that you had a plan created
for a differnt value in the cache.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pr...oads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodin...ions/books.mspx|||rbg,

SqlServerCentral.com has an article on paging. You will need to sign up to
get access.

http://www.sqlteam.com/item.asp?ItemID=26455
-- Bill

"rbg" <rbg.net@.gmail.comwrote in message
news:1169732779.351525.299580@.s48g2000cws.googlegr oups.com...

Quote:

Originally Posted by

>I did use query plans to find out more. ( Please see the thread BELOW)
>
I have a question on this, if someone can help me with that it will be
great.
In my SQL query that selects data from table, I have a where clause
which states :
>
where PermitID like @.WorkType
order by WorkStart DESC
>
@.WorkType is a input parameter to the Stored proc and its value is
'01%'
>
When I use the above where clause, all the Sorts in the ESTIMATED Query
Execution plan show me a COST of 28%.
>
However if I change the query manually to say:
>
where PermitID like '01%'
order by WorkStart DESC
>
The COST of the Sort (in ESTIMATED Query Execution plan) reduces to 2%
and at the beginning of the PLAN, there is a Bookmark Lookup which
includes the above where clause.
Whereas with the FIRST example , the BookMark Lookup in the beginning
doesn't show that where condition.
>
Can anyone help me better understand this anomaly?
>
TIA
=====================================
I am using derived tables to Page data on the SQL Server side.
I used this link as my mentor for doing paging on the SQL
Server
>
http://msdn2.microsoft.com/en-us/library/ms979197.aspx
>
I wanted to use USER PAGING, thus I used the following code:
>
CREATE PROCEDURE UserPaging
(
@.currentPage int = 1, @.pageSize int =1000
)
AS
DECLARE @.Out int, @.rowsToRetrieve int, @.SQLSTRING nvarchar(1000)
>
SET @.rowsToRetrieve = (@.pageSize * @.currentPage)
>
SET NOCOUNT ON
SET @.SQLSTRING = N'select
CustomerID,CompanyName,ContactName,ContactTitle from
( SELECT TOP '+ CAST(@.pageSize as varchar(10)) +
'CustomerId,CompanyName,ContactName,ContactTitle from
( SELECT TOP ' + CAST(@.rowsToRetrieve as varchar(10)) +
'CustomerID,CompanyName,ContactName,ContactTitle FROM
( SELECT TOP ' + CAST(@.rowsToRetrieve as varchar(10)) +
'CustomerID,CompanyName,ContactName,ContactTitle FROM Customers as T1
ORDER BY contactname) AS T2 ORDER BY contactname DESC ) AS T3)
As T4 ORDER BY contactname ASC'
>
EXEC(@.SQLSTRING)
RETURN
GO
>
When I use this. Assume that the Total records returned by the SQL
query is 1198.Thus when I am on Page1 the above Stored Proc (SP) will
return the first 1000 records.
>
This works absolutely fine.
Now I am on Page2, now I need to retrieve only the remaining 198
records.But if I use the above SP, it will return the last 1000
records.So to tweak this I used the following logic to set the
>
@.pagesize variable:
Declare @.PageCount int
select @.PageCount = @.TotalRows/@.PageSize
if @.currentPage @.PageCount SET @.PageSize = @.TotalRows%@.PageSize
>
Since I am on Page2 the above logic will set the PageSize to 198 and
not 1000.But when I use this logic, it takes forever for the SP to
return the 198 records in a resultset.
However if the TotalRows were = 1800, and thus the PageSize=800 or
greater, this SP returns the resultset quickly enough.
>
Thus to get over this problem I had to use the other logic i.e. using
Application Paging (i.e. first storing the entire result set into a
Temp table, then retrieving only the required records for the PAGE)
>
Can anyone suggest what is wrong with my user paging logic???
TIA...
>

|||You are right, I did not include the exact query since it has a whole
of joins and many where clauses in it.
I did not want to make the post very hard to read, hence I simplified
it.

In the Stored proc I am using a String variable @.SQLString
varchar(2000) to hold the entire select statement, and then executing
that SQL using EXEC (@.SQLString).

Thus for debugging, I used Query Analyzer, and within the Analyzer I am
using the Select statement.
So in my test I do not use any stored proc.

so one select statement says:

Select * from ( Select Top 600 * from
( Select Top 2000 * from
( Select Top 2000 PermitNumber, HouseNumber, OnStreetName,
FromStreetName, ToStreetName, WorkStartDate as "WorkStart",
tbl_Permittee.Permittee_name as PermitteeName, PermitteeNumber,
PermitType_ID as "Type",
InspectionDistrict,
PermitStatus,
IssueDate

Quote:

Originally Posted by

>From PermitMain inner join tbl_Permittee


on PermitMain.PermitteeNumber = tbl_Permittee.Permittee_Number
and (tbl_Permittee.Permittee_name_flag = 'd' or
tbl_Permittee.Permittee_name_flag = 'p')
where
(PermitType_ID like '01%' ) and worktypeid is null
and ((IssueDate between @.IssueDateFrom and @.IssueDateTo) or
(EmergIssueDate between @.IssueDateFrom and @.IssueDateTo))
and PermitteeNumber = @.PermitteeNumber
and PermitMain.Boroughcode = @.Boro
order by WorkStart DESC
) as T2 order by WorkStart ASC

) as T3

) as T4 order by WorkStart DESC

THIS ONE RUNS FAST and RETURNS RESULTS.

The Other Select statement:

Select * from ( Select Top 600 * from
( Select Top 2000 * from
( Select Top 2000 PermitNumber, HouseNumber, OnStreetName,
FromStreetName, ToStreetName, WorkStartDate as "WorkStart",
tbl_Permittee.Permittee_name as PermitteeName, PermitteeNumber,
PermitType_ID as "Type",
InspectionDistrict,
PermitStatus,
IssueDate

Quote:

Originally Posted by

>From PermitMain inner join tbl_Permittee


on PermitMain.PermitteeNumber = tbl_Permittee.Permittee_Number
and (tbl_Permittee.Permittee_name_flag = 'd' or
tbl_Permittee.Permittee_name_flag = 'p')
where
(PermitType_ID like @.WokStart ) and worktypeid is null
and ((IssueDate between @.IssueDateFrom and @.IssueDateTo) or
(EmergIssueDate between @.IssueDateFrom and @.IssueDateTo))

and PermitteeNumber = @.PermitteeNumber

and PermitMain.Boroughcode = @.Boro

order by WorkStart DESC

) as T2 order by WorkStart ASC

) as T3

) as T4 order by WorkStart DESC

TAKES FOREVER to COMPLETE.

However IF I INCREASE the PAGESIZE from 600 to 800, BOTH QUERIES RETURN
RESULTS EQUALLY FAST.

Thanks for your help
On Jan 25, 5:49 pm, Erland Sommarskog <esq...@.sommarskog.sewrote:

Quote:

Originally Posted by

rbg (rbg...@.gmail.com) writes:

Quote:

Originally Posted by

I have a question on this, if someone can help me with that it will be
great.
In my SQL query that selects data from table, I have a where clause
which states :


>

Quote:

Originally Posted by

where PermitID like @.WorkType
order by WorkStart DESC


>

Quote:

Originally Posted by

@.WorkType is a input parameter to the Stored proc and its value is
'01%'


>

Quote:

Originally Posted by

When I use the above where clause, all the Sorts in the ESTIMATED Query
Execution plan show me a COST of 28%.


>

Quote:

Originally Posted by

However if I change the query manually to say:


>

Quote:

Originally Posted by

where PermitID like '01%'
order by WorkStart DESC


>

Quote:

Originally Posted by

The COST of the Sort (in ESTIMATED Query Execution plan) reduces to 2%
and at the beginning of the PLAN, there is a Bookmark Lookup which
includes the above where clause.
Whereas with the FIRST example , the BookMark Lookup in the beginning
doesn't show that where condition.


>

Quote:

Originally Posted by

Can anyone help me better understand this anomaly?That WHERE clause was not in your original post. Nor does the column


name seem entirely familiar. I gather that what you posted yesterday
was a sample from an MSDN article, but it can be tricky to give accurate
answers, ir you don't post your actual code.
>
But some optimizer bascis: when SQL Server builds the query plan
for a stored procedure, it builds the plan for the procedure as a
whole. This means that it does not know what values that variables
will have at time for execution. The same applies to parameters, but
in this case it does at least know the input value, and uses this
value as guidance. (This is known as parameter sbiffing.)
>
But SQL Server does not build a query plan every time a procedure
is executed. Instead the plan is put in cache, and the cached plan
will be reused - even if the procedure is called with input values
for which the cached plan is no good.
>
In your case, assume the the procedure was first called with
WorkType '%01'. For this input value any index on PermitID is not
very useful, so most likely you will get a table scan instead.
>
On the other hand, when you hardcode a value. SQL Server have full
information, and the odds for a good plan are much better.
>
To test this theory, you can say:
>
EXEC your_sp @.WorkTyoe WITH RECOMPILE
>
if you get a berrer plan, the problem was that you had a plan created
for a differnt value in the cache.
>
--
Erland Sommarskog, SQL Server MVP, esq...@.sommarskog.se
>
Books Online for SQL Server 2005 athttp://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books...
Books Online for SQL Server 2000 athttp://www.microsoft.com/sql/prodinfo/previousversions/books.mspx

|||PLEASE NOTE the variable was not WokStart but WORKTYPE.

So the query that takes very long looks like this:

Select * from ( Select Top 600 * from
( Select Top 2000 * from
( Select Top 2000 PermitNumber, HouseNumber, OnStreetName,
FromStreetName, ToStreetName, WorkStartDate as "WorkStart",
tbl_Permittee.Permittee_name as PermitteeName, PermitteeNumber,
PermitType_ID as "Type",
InspectionDistrict,
PermitStatus,
IssueDate

Quote:

Originally Posted by

>From PermitMain inner join tbl_Permittee


on PermitMain.PermitteeNumber = tbl_Permittee.Permittee_Number
and (tbl_Permittee.Permittee_name_flag = 'd' or
tbl_Permittee.Permittee_name_flag = 'p')
where
(PermitType_ID like @.WorkType ) and worktypeid is null
and ((IssueDate between @.IssueDateFrom and @.IssueDateTo) or
(EmergIssueDate between @.IssueDateFrom and @.IssueDateTo))

and PermitteeNumber = @.PermitteeNumber

and PermitMain.Boroughcode = @.Boro

order by WorkStart DESC

) as T2 order by WorkStart ASC

) as T3

) as T4 order by WorkStart DESC
================================================== =================
On Jan 26, 8:49 am, "rbg" <rbg...@.gmail.comwrote:

Quote:

Originally Posted by

You are right, I did not include the exact query since it has a whole
of joins and many where clauses in it.
I did not want to make the post very hard to read, hence I simplified
it.
>
In the Stored proc I am using a String variable @.SQLString
varchar(2000) to hold the entire select statement, and then executing
that SQL using EXEC (@.SQLString).
>
Thus for debugging, I used Query Analyzer, and within the Analyzer I am
using the Select statement.
So in my test I do not use any stored proc.
>
so one select statement says:
>
Select * from ( Select Top 600 * from
( Select Top 2000 * from
( Select Top 2000 PermitNumber, HouseNumber, OnStreetName,
FromStreetName, ToStreetName, WorkStartDate as "WorkStart",
tbl_Permittee.Permittee_name as PermitteeName, PermitteeNumber,
PermitType_ID as "Type",
InspectionDistrict,
PermitStatus,
IssueDate>From PermitMain inner join tbl_Permitteeon PermitMain.PermitteeNumber = tbl_Permittee.Permittee_Number
and (tbl_Permittee.Permittee_name_flag = 'd' or
tbl_Permittee.Permittee_name_flag = 'p')
where
(PermitType_ID like '01%' ) and worktypeid is null
and ((IssueDate between @.IssueDateFrom and @.IssueDateTo) or
(EmergIssueDate between @.IssueDateFrom and @.IssueDateTo))
and PermitteeNumber = @.PermitteeNumber
and PermitMain.Boroughcode = @.Boro
order by WorkStart DESC
) as T2 order by WorkStart ASC
>
) as T3
>
) as T4 order by WorkStart DESC
>
THIS ONE RUNS FAST and RETURNS RESULTS.
>
The Other Select statement:
>
Select * from ( Select Top 600 * from
( Select Top 2000 * from
( Select Top 2000 PermitNumber, HouseNumber, OnStreetName,
FromStreetName, ToStreetName, WorkStartDate as "WorkStart",
tbl_Permittee.Permittee_name as PermitteeName, PermitteeNumber,
PermitType_ID as "Type",
InspectionDistrict,
PermitStatus,
IssueDate>From PermitMain inner join tbl_Permitteeon PermitMain.PermitteeNumber = tbl_Permittee.Permittee_Number
and (tbl_Permittee.Permittee_name_flag = 'd' or
tbl_Permittee.Permittee_name_flag = 'p')
where
(PermitType_ID like @.WokStart ) and worktypeid is null
and ((IssueDate between @.IssueDateFrom and @.IssueDateTo) or
(EmergIssueDate between @.IssueDateFrom and @.IssueDateTo))
>
and PermitteeNumber = @.PermitteeNumber
>
and PermitMain.Boroughcode = @.Boro
>
order by WorkStart DESC
>
) as T2 order by WorkStart ASC
>
) as T3
>
) as T4 order by WorkStart DESC
>
TAKES FOREVER to COMPLETE.
>
However IF I INCREASE the PAGESIZE from 600 to 800, BOTH QUERIES RETURN
RESULTS EQUALLY FAST.
>
Thanks for your help
On Jan 25, 5:49 pm, Erland Sommarskog <esq...@.sommarskog.sewrote:
>

Quote:

Originally Posted by

rbg (rbg...@.gmail.com) writes:

Quote:

Originally Posted by

I have a question on this, if someone can help me with that it will be
great.
In my SQL query that selects data from table, I have a where clause
which states :


>

Quote:

Originally Posted by

Quote:

Originally Posted by

where PermitID like @.WorkType
order by WorkStart DESC


>

Quote:

Originally Posted by

Quote:

Originally Posted by

@.WorkType is a input parameter to the Stored proc and its value is
'01%'


>

Quote:

Originally Posted by

Quote:

Originally Posted by

When I use the above where clause, all the Sorts in the ESTIMATED Query
Execution plan show me a COST of 28%.


>

Quote:

Originally Posted by

Quote:

Originally Posted by

However if I change the query manually to say:


>

Quote:

Originally Posted by

Quote:

Originally Posted by

where PermitID like '01%'
order by WorkStart DESC


>

Quote:

Originally Posted by

Quote:

Originally Posted by

The COST of the Sort (in ESTIMATED Query Execution plan) reduces to 2%
and at the beginning of the PLAN, there is a Bookmark Lookup which
includes the above where clause.
Whereas with the FIRST example , the BookMark Lookup in the beginning
doesn't show that where condition.


>

Quote:

Originally Posted by

Quote:

Originally Posted by

Can anyone help me better understand this anomaly?That WHERE clause was not in your original post. Nor does the column


name seem entirely familiar. I gather that what you posted yesterday
was a sample from an MSDN article, but it can be tricky to give accurate
answers, ir you don't post your actual code.


>

Quote:

Originally Posted by

But some optimizer bascis: when SQL Server builds the query plan
for a stored procedure, it builds the plan for the procedure as a
whole. This means that it does not know what values that variables
will have at time for execution. The same applies to parameters, but
in this case it does at least know the input value, and uses this
value as guidance. (This is known as parameter sbiffing.)


>

Quote:

Originally Posted by

But SQL Server does not build a query plan every time a procedure
is executed. Instead the plan is put in cache, and the cached plan
will be reused - even if the procedure is called with input values
for which the cached plan is no good.


>

Quote:

Originally Posted by

In your case, assume the the procedure was first called with
WorkType '%01'. For this input value any index on PermitID is not
very useful, so most likely you will get a table scan instead.


>

Quote:

Originally Posted by

On the other hand, when you hardcode a value. SQL Server have full
information, and the odds for a good plan are much better.


>

Quote:

Originally Posted by

To test this theory, you can say:


>

Quote:

Originally Posted by

EXEC your_sp @.WorkTyoe WITH RECOMPILE


>

Quote:

Originally Posted by

if you get a berrer plan, the problem was that you had a plan created
for a differnt value in the cache.


>

Quote:

Originally Posted by

--
Erland Sommarskog, SQL Server MVP, esq...@.sommarskog.se


>

Quote:

Originally Posted by

Books Online for SQL Server 2005 athttp://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books...
Books Online for SQL Server 2000 athttp://www.microsoft.com/sql/prodinfo/previousversions/books.mspx

|||rbg (rbg.net@.gmail.com) writes:

Quote:

Originally Posted by

In the Stored proc I am using a String variable @.SQLString
varchar(2000) to hold the entire select statement, and then executing
that SQL using EXEC (@.SQLString).
>
Thus for debugging, I used Query Analyzer, and within the Analyzer I am
using the Select statement.
So in my test I do not use any stored proc.
>
so one select statement says:
>...
>
Select * from ( Select Top 600 * from
( Select Top 2000 * from
( Select Top 2000 PermitNumber, HouseNumber, OnStreetName,
FromStreetName, ToStreetName, WorkStartDate as "WorkStart",
tbl_Permittee.Permittee_name as PermitteeName, PermitteeNumber,
PermitType_ID as "Type",
InspectionDistrict,
PermitStatus,
IssueDate

Quote:

Originally Posted by

>>From PermitMain inner join tbl_Permittee


on PermitMain.PermitteeNumber = tbl_Permittee.Permittee_Number
and (tbl_Permittee.Permittee_name_flag = 'd' or
tbl_Permittee.Permittee_name_flag = 'p')
where
(PermitType_ID like @.WokStart ) and worktypeid is null
and ((IssueDate between @.IssueDateFrom and @.IssueDateTo) or
(EmergIssueDate between @.IssueDateFrom and @.IssueDateTo))
and PermitteeNumber = @.PermitteeNumber
and PermitMain.Boroughcode = @.Boro
order by WorkStart DESC
) as T2 order by WorkStart ASC
) as T3
) as T4 order by WorkStart DESC
>
TAKES FOREVER to COMPLETE.


Yes, but how does those variables makes into the dynamic SQL? You said
that you were using EXEC(), and EXEC() does not permit you to pass
parameters. Does your complete SQL string look something like:

DECLARE @.Workstart, ...

SELECT @.Workstart = '01%'
...
SEKECT * ...

Then you have preclsely the problem that I discussed in my previous
post. The optimizer has no clue of value @.workstart has, and will make
a blind assumption.

But you should not use EXEC(). Use sp_executesql instead. sp_executesql
permits you to pass parameters, and in this case the optimizer will
be able to use be parameter values for guidance.

See http://www.sommarskog.se/dynamic_sql.html#sp_executesql for
more details on sp_excecutsql.

If you want further help, please post your entire SQL batch, that is
the one that builds the dynamic SQL. It's a bit frustrating having to
guess what you are doing - and you get better answers that way.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pr...oads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodin...ions/books.mspx|||Please find attached the complete query:

Declare @.WorkType varchar(3), @.PermitteeNumber varchar(5), @.Boro
varchar(1)
Declare @.IssueDateFrom datetime, @.IssueDateTo datetime
Declare @.SortExpression varchar(50), @.SortOrder varchar(5)
Declare @.PageNum int, @.PageSize int

select @.PageNum = 2, @.PageSize = 1000
Declare @.rowsToRetrieve int
Declare @.SortOrderMirror varchar(4)

if @.SortOrder = 'ASC'
SET @.SortOrderMirror = 'DESC'
else
SET @.SortOrderMirror = 'ASC'

SET @.rowsToRetrieve = @.PageNum * @.PageSize

Declare @.TotalRows int

SET @.TotalRows = 1600

SET @.PageSize = @.TotalRows%@.PageSize

select @.WorkType = '01%', @.PermitteeNumber = '00180', @.Boro = 'M'
select @.IssueDateFrom = '01/24/2001', @.IssueDateTo = '01/24/2007'
select @.SortExpression = 'WorkStart', @.SortOrder = 'DESC'

Select * from ( Select Top 600 * from
( Select Top 2000 * from
( Select Top 2000 PermitNumber, HouseNumber, OnStreetName,
FromStreetName, ToStreetName, WorkStartDate as "WorkStart",
tbl_Permittee.Permittee_name as PermitteeName, PermitteeNumber,
PermitType_ID as "Type",
InspectionDistrict,
PermitStatus,
IssueDate

Quote:

Originally Posted by

>From PermitMain inner join tbl_Permittee


on PermitMain.PermitteeNumber = tbl_Permittee.Permittee_Number
and (tbl_Permittee.Permittee_name_flag = 'd' or
tbl_Permittee.Permittee_name_flag = 'p')
where
(PermitType_ID like @.WorkType ) and worktypeid is null
and ((IssueDate between @.IssueDateFrom and @.IssueDateTo) or
(EmergIssueDate between @.IssueDateFrom and @.IssueDateTo))

and PermitteeNumber = @.PermitteeNumber

and PermitMain.Boroughcode = @.Boro

order by WorkStart DESC

) as T2 order by WorkStart ASC

) as T3

) as T4 order by WorkStart DESC
================================================== =====================
=
if I replace the above where clause from PermitType_ID like
@.WorkType to PermitType_ID like '01%'
The results are returned within 30 secs, else it takes forever.

Any Help will be grately appreciated.

TIA..
================================================== =====================
=
On Jan 26, 5:50 pm, Erland Sommarskog <esq...@.sommarskog.sewrote:

Quote:

Originally Posted by

rbg (rbg...@.gmail.com) writes:

Quote:

Originally Posted by

In the Stored proc I am using a String variable @.SQLString
varchar(2000) to hold the entire select statement, and then executing
that SQL using EXEC (@.SQLString).


>

Quote:

Originally Posted by

Thus for debugging, I used Query Analyzer, and within the Analyzer I am
using the Select statement.
So in my test I do not use any stored proc.


>

Quote:

Originally Posted by

so one select statement says:
...


>

Quote:

Originally Posted by

Select * from ( Select Top 600 * from
( Select Top 2000 * from
( Select Top 2000 PermitNumber, HouseNumber, OnStreetName,
FromStreetName, ToStreetName, WorkStartDate as "WorkStart",
tbl_Permittee.Permittee_name as PermitteeName, PermitteeNumber,
PermitType_ID as "Type",
InspectionDistrict,
PermitStatus,
IssueDate

Quote:

Originally Posted by

>From PermitMain inner join tbl_Permittee


on PermitMain.PermitteeNumber = tbl_Permittee.Permittee_Number
and (tbl_Permittee.Permittee_name_flag = 'd' or
tbl_Permittee.Permittee_name_flag = 'p')
where
(PermitType_ID like @.WokStart ) and worktypeid is null
and ((IssueDate between @.IssueDateFrom and @.IssueDateTo) or
(EmergIssueDate between @.IssueDateFrom and @.IssueDateTo))
and PermitteeNumber = @.PermitteeNumber
and PermitMain.Boroughcode = @.Boro
order by WorkStart DESC
) as T2 order by WorkStart ASC
) as T3
) as T4 order by WorkStart DESC


>

Quote:

Originally Posted by

TAKES FOREVER to COMPLETE.Yes, but how does those variables makes into the dynamic SQL? You said


that you were using EXEC(), and EXEC() does not permit you to pass
parameters. Does your complete SQL string look something like:
>
DECLARE @.Workstart, ...
>
SELECT @.Workstart = '01%'
...
SEKECT * ...
>
Then you have preclsely the problem that I discussed in my previous
post. The optimizer has no clue of value @.workstart has, and will make
a blind assumption.
>
But you should not use EXEC(). Use sp_executesql instead. sp_executesql
permits you to pass parameters, and in this case the optimizer will
be able to use be parameter values for guidance.
>
Seehttp://www.sommarskog.se/dynamic_sql.html#sp_executesqlfor
more details on sp_excecutsql.
>
If you want further help, please post your entire SQL batch, that is
the one that builds the dynamic SQL. It's a bit frustrating having to
guess what you are doing - and you get better answers that way.
>
--
Erland Sommarskog, SQL Server MVP, esq...@.sommarskog.se
>
Books Online for SQL Server 2005 athttp://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books...
Books Online for SQL Server 2000 athttp://www.microsoft.com/sql/prodinfo/previousversions/books.mspx

|||Erland,

You were very much right regarding using sp_executesql stored proc for
executing dynamic queries.

Once I started using this:
Declare @.Params nvarchar(200)
SET @.Params = '@.WorkTypeSQL nvarchar(3), @.PermitteeNumberSQL
nvarchar(5), @.BoroSQL nvarchar(1)
exec sp_executesql @.Params, @.WorkType, @.PermitteeNumber, @.Boro

The performance improved and solved my original problem.

I have one more question though.
When I used Temp tables instead of derived tables, my performance
improved significantly. The query which takes 30 seconds using the
derived tables, takes only 11 seconds when using Temp tables.

So is it better to choose the Temp table solution over the derived
tables solution?

TIA

On Jan 29, 9:02 am, "rbg" <rbg...@.gmail.comwrote:

Quote:

Originally Posted by

Please find attached the complete query:
>
Declare @.WorkType varchar(3), @.PermitteeNumber varchar(5), @.Boro
varchar(1)
Declare @.IssueDateFrom datetime, @.IssueDateTo datetime
Declare @.SortExpression varchar(50), @.SortOrder varchar(5)
Declare @.PageNum int, @.PageSize int
>
select @.PageNum = 2, @.PageSize = 1000
Declare @.rowsToRetrieve int
Declare @.SortOrderMirror varchar(4)
>
if @.SortOrder = 'ASC'
SET @.SortOrderMirror = 'DESC'
else
SET @.SortOrderMirror = 'ASC'
>
SET @.rowsToRetrieve = @.PageNum * @.PageSize
>
Declare @.TotalRows int
>
SET @.TotalRows = 1600
>
SET @.PageSize = @.TotalRows%@.PageSize
>
select @.WorkType = '01%', @.PermitteeNumber = '00180', @.Boro = 'M'
select @.IssueDateFrom = '01/24/2001', @.IssueDateTo = '01/24/2007'
select @.SortExpression = 'WorkStart', @.SortOrder = 'DESC'
>
Select * from ( Select Top 600 * from
( Select Top 2000 * from
( Select Top 2000 PermitNumber, HouseNumber, OnStreetName,
FromStreetName, ToStreetName, WorkStartDate as "WorkStart",
tbl_Permittee.Permittee_name as PermitteeName, PermitteeNumber,
PermitType_ID as "Type",
InspectionDistrict,
PermitStatus,
IssueDate>From PermitMain inner join tbl_Permitteeon PermitMain.PermitteeNumber = tbl_Permittee.Permittee_Number
and (tbl_Permittee.Permittee_name_flag = 'd' or
tbl_Permittee.Permittee_name_flag = 'p')
where
(PermitType_ID like @.WorkType ) and worktypeid is null
and ((IssueDate between @.IssueDateFrom and @.IssueDateTo) or
(EmergIssueDate between @.IssueDateFrom and @.IssueDateTo))
>
and PermitteeNumber = @.PermitteeNumber
>
and PermitMain.Boroughcode = @.Boro
>
order by WorkStart DESC
>
) as T2 order by WorkStart ASC
>
) as T3
>
) as T4 order by WorkStart DESC
================================================== =====================
=
if I replace the above where clause from PermitType_ID like
@.WorkType to PermitType_ID like '01%'
The results are returned within 30 secs, else it takes forever.
>
Any Help will be grately appreciated.
>
TIA..
================================================== =====================
=
On Jan 26, 5:50 pm, Erland Sommarskog <esq...@.sommarskog.sewrote:
>

Quote:

Originally Posted by

rbg (rbg...@.gmail.com) writes:

Quote:

Originally Posted by

In the Stored proc I am using a String variable @.SQLString
varchar(2000) to hold the entire select statement, and then executing
that SQL using EXEC (@.SQLString).


>

Quote:

Originally Posted by

Quote:

Originally Posted by

Thus for debugging, I used Query Analyzer, and within the Analyzer I am
using the Select statement.
So in my test I do not use any stored proc.


>

Quote:

Originally Posted by

Quote:

Originally Posted by

so one select statement says:
>...


>

Quote:

Originally Posted by

Quote:

Originally Posted by

Select * from ( Select Top 600 * from
( Select Top 2000 * from
( Select Top 2000 PermitNumber, HouseNumber, OnStreetName,
FromStreetName, ToStreetName, WorkStartDate as "WorkStart",
tbl_Permittee.Permittee_name as PermitteeName, PermitteeNumber,
PermitType_ID as "Type",
InspectionDistrict,
PermitStatus,
IssueDate
>>From PermitMain inner join tbl_Permittee
on PermitMain.PermitteeNumber = tbl_Permittee.Permittee_Number
and (tbl_Permittee.Permittee_name_flag = 'd' or
tbl_Permittee.Permittee_name_flag = 'p')
where
(PermitType_ID like @.WokStart ) and worktypeid is null
and ((IssueDate between @.IssueDateFrom and @.IssueDateTo) or
(EmergIssueDate between @.IssueDateFrom and @.IssueDateTo))
and PermitteeNumber = @.PermitteeNumber
and PermitMain.Boroughcode = @.Boro
order by WorkStart DESC
) as T2 order by WorkStart ASC
) as T3
) as T4 order by WorkStart DESC


>

Quote:

Originally Posted by

Quote:

Originally Posted by

TAKES FOREVER to COMPLETE.Yes, but how does those variables makes into the dynamic SQL? You said


that you were using EXEC(), and EXEC() does not permit you to pass
parameters. Does your complete SQL string look something like:


>

Quote:

Originally Posted by

DECLARE @.Workstart, ...


>

Quote:

Originally Posted by

SELECT @.Workstart = '01%'
...
SEKECT * ...


>

Quote:

Originally Posted by

Then you have preclsely the problem that I discussed in my previous
post. The optimizer has no clue of value @.workstart has, and will make
a blind assumption.


>

Quote:

Originally Posted by

But you should not use EXEC(). Use sp_executesql instead. sp_executesql
permits you to pass parameters, and in this case the optimizer will
be able to use be parameter values for guidance.


>

Quote:

Originally Posted by

Seehttp://www.sommarskog.se/dynamic_sql.html#sp_executesqlfor
more details on sp_excecutsql.


>

Quote:

Originally Posted by

If you want further help, please post your entire SQL batch, that is
the one that builds the dynamic SQL. It's a bit frustrating having to
guess what you are doing - and you get better answers that way.


>

Quote:

Originally Posted by

--
Erland Sommarskog, SQL Server MVP, esq...@.sommarskog.se


>

Quote:

Originally Posted by

Books Online for SQL Server 2005 athttp://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books...
Books Online for SQL Server 2000 athttp://www.microsoft.com/sql/prodinfo/previousversions/books.mspx

|||rbg (rbg.net@.gmail.com) writes:

Quote:

Originally Posted by

I have one more question though.
When I used Temp tables instead of derived tables, my performance
improved significantly. The query which takes 30 seconds using the
derived tables, takes only 11 seconds when using Temp tables.
>
So is it better to choose the Temp table solution over the derived
tables solution?


So instead of the derived tables, you did the SELECT TOP into the
temp tables? Or did you use the temp tables in any other way?

Assuming the first, this is one of those hairy questions of which the
short answer is "it depends". In most cases, it's more effecient to do
all in one query, rather than matierialising the intermediate results
in a temp table. This is because the optimizer may find ways to recast
the computation order without affecting the final result. But there are
always exceptions. In this particular case, the optimizer may not have
been able to find a shortcut. On the other hand, the temp table has
statistics, so when coming to the next query, the optimizer has more
information and may find a better plan.

I'm glad to hear that sp_executesql resolved your problems!

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pr...oads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodin...ions/books.mspx