Home All Groups Group Topic Archive Search About

Help with Stored Procedure, Taking too long to run...

Author
9 Mar 2006 6:05 PM
RL Tech
Hello,

I have a stored procedure that i've been using for the past 2 years... it
has started to slow down on some of the complex searches... But i'll provide
the tables and a clean version of the stored procedure for anyone who can
help... (clean showing procedure without commented stuff out)..

I'm running SQL Server 2000 at this time... i plan on upgrading to SQL
Server 2005 in the very near future...

To sum up, this stored procedure will read data from two identical tables,
one with 100k records, and the other with 600k records.  The records are
sorted into a temp table, and then the records for page XX are extracted
based on how many records per page is requested.  All paging happens server
side, this way only the data required is returned.

I also have 3 other tables that are used with these tables, but they aren't
used as much...

I do have fulltext set up on Items and PubItems tables...

When a search is done by ISBN on both, the time taken is between 100 and 500
MS...
When i do a search (say by title or author), the time taken is between 1000
MS and ... well, i've seen numbers up around 200000 MS or higher...

I'm not going to provide any data inserts as trying to run this against a
table with 5-100 records isn't going to show how slow my searches can be...
Example procedure runs:
1: exec sp_PagedItems4 'Both','I.ISBN=''9781111111113''','TitleIndex',1,15
1: This search was under 1 second, and returned the one record as expected.
2: exec sp_PagedItems4 'Both','I.TitleText Like
''%Garfield%''','TitleIndex',1,15
2: This search took 5 seconds, and returned the 15 records for page 1, but
overall count is 265.
3: exec sp_PagedItems4 'Both',
'(FREETEXT (I.TitleText, ''"books"'') OR FREETEXT (I.Subtitle, ''"books"'')
OR FREETEXT (I.AuthorText, ''"books"'') OR FREETEXT (I.IllusText,
''"books"''))  AND  (FREETEXT (I.TitleText, ''"about"'') OR FREETEXT
(I.Subtitle, ''"about"'') OR FREETEXT (I.AuthorText, ''"about"'') OR
FREETEXT (I.IllusText, ''"about"''))  AND  (FREETEXT (I.TitleText,
''"crafts"'') OR FREETEXT (I.Subtitle, ''"crafts"'') OR FREETEXT
(I.AuthorText, ''"crafts"'') OR FREETEXT (I.IllusText, ''"crafts"''))'
,'TitleIndex',1,15
3: This search took 1 minute and 45 seconds (when run from SQL Query
Analyzer), and returned ONE record from PubItems.

Any help is very much appreciated...
Thanks!

----------------------------------------------------------------------------
----------------------------
CREATE TABLE [dbo].[AwardType] (
[AwardCode] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[AwardDesc] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[Awards] (
[ItemID] [int] NOT NULL ,
[AwardCode] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[ReviewType] (
[ReviewCode] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
,
[ReviewDesc] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[Reviews] (
[ItemID] [int] NOT NULL ,
[ReviewCode] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
) ON [PRIMARY]
GO

CREATE TABLE Items
(
ID int IDENTITY(1,1) PRIMARY KEY,
ItemID int null,
PubSource nvarchar(255) default (''),
ISBN nvarchar(13) null,
Dewey nvarchar(20) null,
TitleIndex nvarchar(175) null,
AuthorIndex nvarchar(50) null,
PubYear nvarchar(30) null,
PubDate datetime null,
SeriesName nvarchar(150) null,
SeriesNumber int null
)
GO

CREATE TABLE PubItems
(
ID int IDENTITY(1,1) PRIMARY KEY,
ItemID int null,
PubSource nvarchar(255) default (''),
ISBN nvarchar(13) null,
Dewey nvarchar(20) null,
TitleIndex nvarchar(175) null,
AuthorIndex nvarchar(50) null,
PubYear nvarchar(30) null,
PubDate datetime null,
SeriesName nvarchar(150) null,
SeriesNumber int null
)
GO

/*
sp_PagedItems4 -

This procedure is the continuation of the original sp_PagedItems, which
would allow us to grab records from BOTH Items and PubItems, and
eliminate the Items in the PubItems Table which are in Items.  The only
difference here is that we only return the minimal data fields (which
should
hopefully speed up the query).
*/

CREATE PROCEDURE sp_PagedItems4
(
@TableExt nvarchar(10),
@Where nvarchar(1500),
@SortColumn nvarchar(300),
@Page int,
@RecsPerPage int
)
WITH RECOMPILE
AS
DECLARE @Where2 nvarchar(1500)
DECLARE @Table nvarchar(200)
DECLARE @Table2 nvarchar(200)
DECLARE @Fields nvarchar(2000)
DECLARE @Fields2 nvarchar(2000)
DECLARE @FieldsInsert nvarchar(2000)
DECLARE @FieldsI nvarchar(2000)

DECLARE @query nvarchar(4000)
DECLARE @TotalRec int

DECLARE @AwardReview char(1)

Set @AwardReview = 'N'
Set @Where2 = @Where
Set @Where2 = REPLACE(@Where2,'I.','PI.')

--Fields, Blurb, SecBlurb, SetID, BestBlurb are ntext fields.  These fields
need to be removed from the union, but put in after
--the data is done.
Set @Fields = 'I.ItemID, '''', I.ISBN, I.Dewey, I.TitleIndex, I.AuthorIndex,
I.PubYear, I.PubDate, I.SeriesName, I.SeriesNumber'
Set @Fields2 = 'PI.ItemID, PI.PubSource, PI.ISBN, PI.Dewey, PI.TitleIndex,
PI.AuthorIndex, PI.PubYear, PI.PubDate, PI.SeriesName, PI.SeriesNumber'

Set @Table = 'Items I'
Set @Table2 = 'PubItems PI'

Set @FieldsI = 'I.ItemID, I.PubSource, I.ISBN, I.Dewey, I.TitleIndex,
I.AuthorIndex, I.PubYear, I.PubDate, I.SeriesName, I.SeriesNumber'

--Check for "A", "R" or "AD" in the Where as we need to join the tables if
that's the case. (Items only)
if charindex('A.', @Where) > 0
begin
Set @Table = @Table + ' JOIN Awards A ON I.ItemID = A.ItemID '
Set @AwardReview = 'Y'
end

if charindex('R.', @Where) > 0
begin
Set @Table = @Table + ' JOIN Reviews R ON I.ItemID = R.ItemID '
Set @AwardReview = 'Y'
end

-- Do not return # rows inserted in temp table.
SET NOCOUNT ON

--Create Temp Table
CREATE TABLE #TempItems
(
ID int IDENTITY(1,1) PRIMARY KEY,
ItemID int null,
PubSource nvarchar(255) default (''),
ISBN nvarchar(13) null,
Dewey nvarchar(20) null,
TitleIndex nvarchar(175) null,
AuthorIndex nvarchar(50) null,
PubYear nvarchar(30) null,
PubDate datetime null,
SeriesName nvarchar(150) null,
SeriesNumber int null
)

-- Insert the rows from Items into the temp table.
if @AwardReview = 'N'
begin
--No Award/Review, let's union this...
if @tableext = 'Both' Or @TableExt = 'Items'
begin
  SELECT @query = 'INSERT INTO #TempItems ' +
   ' (' + @FieldsI + ') ' +
   ' SELECT ' + @Fields +
   ' FROM ' + @Table +
   ' WHERE ' + @Where
end

if @tableext = 'Both'
begin
  Select @query = @query + ' UNION ' +
   ' SELECT ' + @Fields2 +
   ' FROM ' + @Table2 +
   ' WHERE ' + @Where2
end

if @TableExt = 'PubItems'
begin
  SELECT @query =  'INSERT INTO #TempItems ' +
   ' (' + @Fields2 + ') ' +
   ' SELECT ' + @Fields2 +
   ' FROM ' + @Table2 +
   ' WHERE ' + @Where2
end

if @SortColumn <> '' And Not isnull(@SortColumn,'') = ''
  SELECT @query = @query + ' ORDER BY ' + @SortColumn

--Print @Query
exec sp_executesql @query
end
else
begin
--There is an award/review requested, so don't even look at pubitems
if @tableext = 'Both' Or @TableExt = 'Items'
begin
  SELECT @query = 'INSERT INTO #TempItems ' +
   ' (' + @FieldsI + ') ' +
   ' SELECT ' + @Fields +
   ' FROM ' + @Table +
   ' WHERE ' + @Where

  if @SortColumn <> '' And Not isnull(@SortColumn,'') = ''
   SELECT @query = @query + ' ORDER BY ' + @SortColumn
  --print @query
  exec sp_executesql @query
end
end

SET @TotalRec =
(SELECT COUNT(ID)
FROM #TempItems)

--Check if there are any records.  If there are, return everything, else
return all zeros and
--no resultset.
if @TotalRec > 0
begin
DECLARE @MoreRecords int
DECLARE @FirstRec int
DECLARE @LastRec int
DECLARE @DispFirstRec int
DECLARE @DispLastRec int

/*Find out first and last record we want
  If Page=0, then we want all records!
*/

if @Page = 0
begin

  SELECT @FirstRec = 0
  SELECT @LastRec = @TotalRec + 1
end
else
begin
  SELECT @FirstRec = (@Page - 1) * @RecsPerPage
  SELECT @LastRec = (@Page * @RecsPerPage + 1)
end

-- Now return the set of paged records, plus an indication if we
-- have more to return or not.
SET @MoreRecords =
  (SELECT COUNT(ID)
  FROM #TempItems TI
  WHERE TI.ID >= @LastRec)

-- Check @FirstRec & @LastRec.
-- @FirstRec should always be +1 based on the record count.
Set @DispFirstRec = @FirstRec + 1

-- @LastRec should be +1 unless it is on the last page.
if @LastRec > @TotalRec
  Set @DispLastRec = @TotalRec
else
  Set @DispLastRec = @LastRec - 1

--First ResultSet (TotalRec, MoreRecords, FirstRec, LastRec
SELECT TotalRec = @TotalRec, MoreRecords = @MoreRecords, FirstRec =
@DispFirstRec, LastRec = @DispLastRec
--Second ResultSet (All Records)
SELECT ID, ItemID, PubSource, ISBN
FROM #TempItems
  WHERE ID>@FirstRec AND ID<@LastRec

--exec sp_executesql @query
end
else
begin
--Empty ResultSet (Return all Zeros)
SELECT TotalRec = 0, MoreRecords = 0, FirstRec = 0, LastRec =0
SELECT @query
end

--Don't need the Drop table as its automatically done after this procedure
is done.
--DROP TABLE #TempItems

-- Turn NOCOUNT back OFF

SET NOCOUNT OFF
GO

Author
13 Mar 2006 4:50 PM
RL Tech
Hi,

Is there anyone able to help me out with this?

Show quote
"RL Tech" <tech_support@nospamuls.com> wrote in message
news:%23PKjbQ6QGHA.1096@TK2MSFTNGP11.phx.gbl...
> Hello,
>
> I have a stored procedure that i've been using for the past 2 years... it
> has started to slow down on some of the complex searches... But i'll
provide
> the tables and a clean version of the stored procedure for anyone who can
> help... (clean showing procedure without commented stuff out)..
>
> I'm running SQL Server 2000 at this time... i plan on upgrading to SQL
> Server 2005 in the very near future...
>
> To sum up, this stored procedure will read data from two identical tables,
> one with 100k records, and the other with 600k records.  The records are
> sorted into a temp table, and then the records for page XX are extracted
> based on how many records per page is requested.  All paging happens
server
> side, this way only the data required is returned.
>
> I also have 3 other tables that are used with these tables, but they
aren't
> used as much...
>
> I do have fulltext set up on Items and PubItems tables...
>
> When a search is done by ISBN on both, the time taken is between 100 and
500
> MS...
> When i do a search (say by title or author), the time taken is between
1000
> MS and ... well, i've seen numbers up around 200000 MS or higher...
>
> I'm not going to provide any data inserts as trying to run this against a
> table with 5-100 records isn't going to show how slow my searches can
be...
> Example procedure runs:
> 1: exec sp_PagedItems4 'Both','I.ISBN=''9781111111113''','TitleIndex',1,15
> 1: This search was under 1 second, and returned the one record as
expected.
> 2: exec sp_PagedItems4 'Both','I.TitleText Like
> ''%Garfield%''','TitleIndex',1,15
> 2: This search took 5 seconds, and returned the 15 records for page 1, but
> overall count is 265.
> 3: exec sp_PagedItems4 'Both',
> '(FREETEXT (I.TitleText, ''"books"'') OR FREETEXT (I.Subtitle,
''"books"'')
> OR FREETEXT (I.AuthorText, ''"books"'') OR FREETEXT (I.IllusText,
> ''"books"''))  AND  (FREETEXT (I.TitleText, ''"about"'') OR FREETEXT
> (I.Subtitle, ''"about"'') OR FREETEXT (I.AuthorText, ''"about"'') OR
> FREETEXT (I.IllusText, ''"about"''))  AND  (FREETEXT (I.TitleText,
> ''"crafts"'') OR FREETEXT (I.Subtitle, ''"crafts"'') OR FREETEXT
> (I.AuthorText, ''"crafts"'') OR FREETEXT (I.IllusText, ''"crafts"''))'
> ,'TitleIndex',1,15
> 3: This search took 1 minute and 45 seconds (when run from SQL Query
> Analyzer), and returned ONE record from PubItems.
>
> Any help is very much appreciated...
> Thanks!
>
> --------------------------------------------------------------------------
--
> ----------------------------
> CREATE TABLE [dbo].[AwardType] (
>  [AwardCode] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
,
>  [AwardDesc] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
> ) ON [PRIMARY]
> GO
>
> CREATE TABLE [dbo].[Awards] (
>  [ItemID] [int] NOT NULL ,
>  [AwardCode] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
> ) ON [PRIMARY]
> GO
>
> CREATE TABLE [dbo].[ReviewType] (
>  [ReviewCode] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT
NULL
> ,
>  [ReviewDesc] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
> ) ON [PRIMARY]
> GO
>
> CREATE TABLE [dbo].[Reviews] (
>  [ItemID] [int] NOT NULL ,
>  [ReviewCode] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT
NULL
> ) ON [PRIMARY]
> GO
>
> CREATE TABLE Items
> (
>  ID int IDENTITY(1,1) PRIMARY KEY,
>  ItemID int null,
>  PubSource nvarchar(255) default (''),
>  ISBN nvarchar(13) null,
>  Dewey nvarchar(20) null,
>  TitleIndex nvarchar(175) null,
>  AuthorIndex nvarchar(50) null,
>  PubYear nvarchar(30) null,
>  PubDate datetime null,
>  SeriesName nvarchar(150) null,
>  SeriesNumber int null
> )
> GO
>
> CREATE TABLE PubItems
> (
>  ID int IDENTITY(1,1) PRIMARY KEY,
>  ItemID int null,
>  PubSource nvarchar(255) default (''),
>  ISBN nvarchar(13) null,
>  Dewey nvarchar(20) null,
>  TitleIndex nvarchar(175) null,
>  AuthorIndex nvarchar(50) null,
>  PubYear nvarchar(30) null,
>  PubDate datetime null,
>  SeriesName nvarchar(150) null,
>  SeriesNumber int null
> )
> GO
>
> /*
>  sp_PagedItems4 -
>
>  This procedure is the continuation of the original sp_PagedItems, which
>  would allow us to grab records from BOTH Items and PubItems, and
>  eliminate the Items in the PubItems Table which are in Items.  The only
>  difference here is that we only return the minimal data fields (which
> should
>  hopefully speed up the query).
> */
>
> CREATE PROCEDURE sp_PagedItems4
> (
>  @TableExt nvarchar(10),
>  @Where nvarchar(1500),
>  @SortColumn nvarchar(300),
>  @Page int,
>  @RecsPerPage int
> )
> WITH RECOMPILE
> AS
> DECLARE @Where2 nvarchar(1500)
> DECLARE @Table nvarchar(200)
> DECLARE @Table2 nvarchar(200)
> DECLARE @Fields nvarchar(2000)
> DECLARE @Fields2 nvarchar(2000)
> DECLARE @FieldsInsert nvarchar(2000)
> DECLARE @FieldsI nvarchar(2000)
>
> DECLARE @query nvarchar(4000)
> DECLARE @TotalRec int
>
> DECLARE @AwardReview char(1)
>
> Set @AwardReview = 'N'
> Set @Where2 = @Where
> Set @Where2 = REPLACE(@Where2,'I.','PI.')
>
> --Fields, Blurb, SecBlurb, SetID, BestBlurb are ntext fields.  These
fields
> need to be removed from the union, but put in after
> --the data is done.
> Set @Fields = 'I.ItemID, '''', I.ISBN, I.Dewey, I.TitleIndex,
I.AuthorIndex,
> I.PubYear, I.PubDate, I.SeriesName, I.SeriesNumber'
> Set @Fields2 = 'PI.ItemID, PI.PubSource, PI.ISBN, PI.Dewey, PI.TitleIndex,
> PI.AuthorIndex, PI.PubYear, PI.PubDate, PI.SeriesName, PI.SeriesNumber'
>
> Set @Table = 'Items I'
> Set @Table2 = 'PubItems PI'
>
> Set @FieldsI = 'I.ItemID, I.PubSource, I.ISBN, I.Dewey, I.TitleIndex,
> I.AuthorIndex, I.PubYear, I.PubDate, I.SeriesName, I.SeriesNumber'
>
> --Check for "A", "R" or "AD" in the Where as we need to join the tables if
> that's the case. (Items only)
> if charindex('A.', @Where) > 0
> begin
>  Set @Table = @Table + ' JOIN Awards A ON I.ItemID = A.ItemID '
>  Set @AwardReview = 'Y'
> end
>
> if charindex('R.', @Where) > 0
> begin
>  Set @Table = @Table + ' JOIN Reviews R ON I.ItemID = R.ItemID '
>  Set @AwardReview = 'Y'
> end
>
> -- Do not return # rows inserted in temp table.
> SET NOCOUNT ON
>
> --Create Temp Table
> CREATE TABLE #TempItems
> (
>  ID int IDENTITY(1,1) PRIMARY KEY,
>  ItemID int null,
>  PubSource nvarchar(255) default (''),
>  ISBN nvarchar(13) null,
>  Dewey nvarchar(20) null,
>  TitleIndex nvarchar(175) null,
>  AuthorIndex nvarchar(50) null,
>  PubYear nvarchar(30) null,
>  PubDate datetime null,
>  SeriesName nvarchar(150) null,
>  SeriesNumber int null
> )
>
> -- Insert the rows from Items into the temp table.
> if @AwardReview = 'N'
> begin
>  --No Award/Review, let's union this...
>  if @tableext = 'Both' Or @TableExt = 'Items'
>  begin
>   SELECT @query = 'INSERT INTO #TempItems ' +
>    ' (' + @FieldsI + ') ' +
>    ' SELECT ' + @Fields +
>    ' FROM ' + @Table +
>    ' WHERE ' + @Where
>  end
>
>  if @tableext = 'Both'
>  begin
>   Select @query = @query + ' UNION ' +
>    ' SELECT ' + @Fields2 +
>    ' FROM ' + @Table2 +
>    ' WHERE ' + @Where2
>  end
>
>  if @TableExt = 'PubItems'
>  begin
>   SELECT @query =  'INSERT INTO #TempItems ' +
>    ' (' + @Fields2 + ') ' +
>    ' SELECT ' + @Fields2 +
>    ' FROM ' + @Table2 +
>    ' WHERE ' + @Where2
>  end
>
>  if @SortColumn <> '' And Not isnull(@SortColumn,'') = ''
>   SELECT @query = @query + ' ORDER BY ' + @SortColumn
>
>  --Print @Query
>  exec sp_executesql @query
> end
> else
> begin
>  --There is an award/review requested, so don't even look at pubitems
>  if @tableext = 'Both' Or @TableExt = 'Items'
>  begin
>   SELECT @query = 'INSERT INTO #TempItems ' +
>    ' (' + @FieldsI + ') ' +
>    ' SELECT ' + @Fields +
>    ' FROM ' + @Table +
>    ' WHERE ' + @Where
>
>   if @SortColumn <> '' And Not isnull(@SortColumn,'') = ''
>    SELECT @query = @query + ' ORDER BY ' + @SortColumn
>   --print @query
>   exec sp_executesql @query
>  end
> end
>
> SET @TotalRec =
>  (SELECT COUNT(ID)
>  FROM #TempItems)
>
> --Check if there are any records.  If there are, return everything, else
> return all zeros and
> --no resultset.
> if @TotalRec > 0
> begin
>  DECLARE @MoreRecords int
>  DECLARE @FirstRec int
>  DECLARE @LastRec int
>  DECLARE @DispFirstRec int
>  DECLARE @DispLastRec int
>
>  /*Find out first and last record we want
>   If Page=0, then we want all records!
>  */
>
>  if @Page = 0
>  begin
>
>   SELECT @FirstRec = 0
>   SELECT @LastRec = @TotalRec + 1
>  end
>  else
>  begin
>   SELECT @FirstRec = (@Page - 1) * @RecsPerPage
>   SELECT @LastRec = (@Page * @RecsPerPage + 1)
>  end
>
>  -- Now return the set of paged records, plus an indication if we
>  -- have more to return or not.
>  SET @MoreRecords =
>   (SELECT COUNT(ID)
>   FROM #TempItems TI
>   WHERE TI.ID >= @LastRec)
>
>  -- Check @FirstRec & @LastRec.
>  -- @FirstRec should always be +1 based on the record count.
>  Set @DispFirstRec = @FirstRec + 1
>
>  -- @LastRec should be +1 unless it is on the last page.
>  if @LastRec > @TotalRec
>   Set @DispLastRec = @TotalRec
>  else
>   Set @DispLastRec = @LastRec - 1
>
>  --First ResultSet (TotalRec, MoreRecords, FirstRec, LastRec
>  SELECT TotalRec = @TotalRec, MoreRecords = @MoreRecords, FirstRec =
> @DispFirstRec, LastRec = @DispLastRec
>  --Second ResultSet (All Records)
>  SELECT ID, ItemID, PubSource, ISBN
>  FROM #TempItems
>   WHERE ID>@FirstRec AND ID<@LastRec
>
>  --exec sp_executesql @query
> end
> else
> begin
>  --Empty ResultSet (Return all Zeros)
>  SELECT TotalRec = 0, MoreRecords = 0, FirstRec = 0, LastRec =0
>  SELECT @query
> end
>
> --Don't need the Drop table as its automatically done after this procedure
> is done.
> --DROP TABLE #TempItems
>
> -- Turn NOCOUNT back OFF
>
> SET NOCOUNT OFF
> GO
>
>
Author
13 Mar 2006 10:06 PM
markc600
After a quick look, a fews comments...
First, there are other ways to do paging, see
http://www.aspfaq.com/show.asp?id=2120
If you move to SQL Server 2005, you can also use ROW_NUMBER()...OVER()

You have two tables (Items and PubItems) with identical columns which
you UNION together, this will eliminate duplicates based on
all column which can be expensive. Why isn't this a single table?
Your JOINs to Awards and Reviews could use EXISTS.

You are copying all of your data into your
temporary table (presumably becasue of the earlier UNION).
You may find it more efficient to copy only the keys
(not in your DDL) and then join the page from your
temporary table back to your main tables.

The SELECT that returns the data

SELECT ID, ItemID, PubSource, ISBN
FROM #TempItems

should really have an ORDER BY ID as the order isn't guaranteed
otherwise.
Author
14 Mar 2006 5:34 PM
RL Tech
Thank you for taking the time to look over my script...
I wrote that script based on what was available at the time and known about
paging... i see by the link at aspfaq, that there has been some improvements
in the ways paging works... i'll see what i can do to implement these
possible changes...

You did mention that in SQL Server 2005, i can use these new commands
(ROW_NUMBER, OVER)... have you used these commands yourself? i'm just
curious on how much better they are...  We are considering moving up to sql
server 2005, but really just looking at cost differences, and also the time
required for me to learn the new server (as i have not had time to learn
about it...)

These 2 tables aren't a single table mainly because i wanted to keep the
data separate (as the source of the data is different for both)... but i did
want to allow users to search both tables at the same time (if they wished).
I'll have to consider putting them in one table, but would rather keep it
separate.

You mentioned that i could use EXISTS for the JOINs to Awards/Reviews.. do
you have an example on how i would use that?  Thanks...

I copied all the data into the temp table, (not because of the union, as i
original had it doing two inserts/selects based on the table requests)... i
found the union to actually be faster than using insert/select twice.. but i
cut down the # of fields from the original (around 80 fields) to the current
10... This way the website will pull each record individually once the ID #
is known...

Fair enough with the order by id... i guess it never happened where the
items weren't actually in order because i have an order by (sort by param by
customer profile) which is passed in and handled that way...

I thank you for your response, and look forward to any further possible
fixes..


<markc***@hotmail.com> wrote in message
Show quote
news:1142287604.330301.206650@p10g2000cwp.googlegroups.com...
> After a quick look, a fews comments...
> First, there are other ways to do paging, see
> http://www.aspfaq.com/show.asp?id=2120
> If you move to SQL Server 2005, you can also use ROW_NUMBER()...OVER()
>
> You have two tables (Items and PubItems) with identical columns which
> you UNION together, this will eliminate duplicates based on
> all column which can be expensive. Why isn't this a single table?
> Your JOINs to Awards and Reviews could use EXISTS.
>
> You are copying all of your data into your
> temporary table (presumably becasue of the earlier UNION).
> You may find it more efficient to copy only the keys
> (not in your DDL) and then join the page from your
> temporary table back to your main tables.
>
> The SELECT that returns the data
>
>  SELECT ID, ItemID, PubSource, ISBN
>  FROM #TempItems
>
> should really have an ORDER BY ID as the order isn't guaranteed
> otherwise.
>
Author
15 Mar 2006 10:05 AM
markc600
Assuming that the Items and PubItems are now the single
table (PubItems) with an extra column to determine the source

   ItemSource CHAR(1) NOT NULL CHECK (ItemSource IN ('I','P'))

and there is a unique constraint somewhere, e.g.

   ISBN nvarchar(13) NOT NULL ,
   UNIQUE (ISBN),

using SQL Server 2005, you can do this, without requiring
a temporary table

WITH CTE_PubItems(ID, ItemID, PubSource, ISBN)
AS
(
SELECT ROW_NUMBER() OVER(ORDER BY P.Dewey, P.TitleIndex),
        P.ItemID, P.PubSource, P.ISBN
FROM PubItems P
WHERE ItemSource ='P'
AND EXISTS(SELECT * FROM Awards A WHERE P.ItemID = A.ItemID
            AND A.AwardCode='???')
AND EXISTS(SELECT * FROM Reviews R WHERE P.ItemID = R.ItemID
            AND R.ReviewCode='???')
-- AND other conditions
)
SELECT ID, ItemID, PubSource, ISBN
FROM CTE_PubItems
WHERE ID>@FirstRec AND ID<@LastRec
ORDER BY ID

You'll have to use dynamic SQL as your
WHERE clause and ORDER BY are user-defined.
Author
16 Mar 2006 6:24 PM
RL Tech
Good to know.. thanks for the information...
If i ever move to 2005, then i'll have something to read up (and lots to
learn) if we move to it..

Thanks again.

<markc***@hotmail.com> wrote in message
Show quote
news:1142417136.877267.81450@j33g2000cwa.googlegroups.com...
> Assuming that the Items and PubItems are now the single
> table (PubItems) with an extra column to determine the source
>
>    ItemSource CHAR(1) NOT NULL CHECK (ItemSource IN ('I','P'))
>
> and there is a unique constraint somewhere, e.g.
>
>    ISBN nvarchar(13) NOT NULL ,
>    UNIQUE (ISBN),
>
> using SQL Server 2005, you can do this, without requiring
> a temporary table
>
> WITH CTE_PubItems(ID, ItemID, PubSource, ISBN)
> AS
> (
>  SELECT ROW_NUMBER() OVER(ORDER BY P.Dewey, P.TitleIndex),
>         P.ItemID, P.PubSource, P.ISBN
>  FROM PubItems P
>  WHERE ItemSource ='P'
>  AND EXISTS(SELECT * FROM Awards A WHERE P.ItemID = A.ItemID
>             AND A.AwardCode='???')
>  AND EXISTS(SELECT * FROM Reviews R WHERE P.ItemID = R.ItemID
>             AND R.ReviewCode='???')
>  -- AND other conditions
> )
> SELECT ID, ItemID, PubSource, ISBN
> FROM CTE_PubItems
> WHERE ID>@FirstRec AND ID<@LastRec
> ORDER BY ID
>
> You'll have to use dynamic SQL as your
> WHERE clause and ORDER BY are user-defined.
>
Author
20 Mar 2006 5:43 PM
RL Tech
Hello again,

At this moment, we cannot move to SQL 2005.... so i need some help with this
still in increasing the response time with this stored procedure..

I'm not sure if my indexes are correct, although i imagine it is correct as
searches work and are somewhat quick.

I'd like to leave the 2 tables as 2 tables for now...

Anyone else have any other suggestions?

Thanks.

<markc***@hotmail.com> wrote in message
Show quote
news:1142287604.330301.206650@p10g2000cwp.googlegroups.com...
> After a quick look, a fews comments...
> First, there are other ways to do paging, see
> http://www.aspfaq.com/show.asp?id=2120
> If you move to SQL Server 2005, you can also use ROW_NUMBER()...OVER()
>
> You have two tables (Items and PubItems) with identical columns which
> you UNION together, this will eliminate duplicates based on
> all column which can be expensive. Why isn't this a single table?
> Your JOINs to Awards and Reviews could use EXISTS.
>
> You are copying all of your data into your
> temporary table (presumably becasue of the earlier UNION).
> You may find it more efficient to copy only the keys
> (not in your DDL) and then join the page from your
> temporary table back to your main tables.
>
> The SELECT that returns the data
>
>  SELECT ID, ItemID, PubSource, ISBN
>  FROM #TempItems
>
> should really have an ORDER BY ID as the order isn't guaranteed
> otherwise.
>

AddThis Social Bookmark Button