Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Development (2000)
 Query works but too slow to use :(

Author  Topic 

nmg196
Yak Posting Veteran

70 Posts

Posted - 2006-05-12 : 08:10:34
Hi,

I have a query which returns companies based on their type. There is a link table which links companies to types and it has a few thousand rows in it.

The problem is that the query is too slow to use and I can't see why.

I pass in a CSV list of types (optionally). The idea is that IF the list of types is not null, it will return the list of companies that have a type that's in the list. The problem is, the more types you pass in, the slower the query is. It's taking quite a while (10-30 seconds) to execute if you select 3 types which is too slow to be used on the website.

I can speed it up a bit by generating the list of EntryIDs of the right type as a temp table FIRST, then querying against the temp table, but it doesn't make a huge difference.

I can't see why this query would take so long to execute.

Can somebody please point out if there's a faster way of doing this.


ALTER PROCEDURE [dbo].[SearchCompaniesFiltered]
@Name nvarchar(100) = null,
@ProductionTypes nvarchar(20) = null
AS
BEGIN

declare @ProductionTypesTable TABLE (
ProductionTypeID int
)

IF @productionTypes is not null BEGIN
set nocount on
declare @separator char(1)
select @separator = ','
declare @separator_position int -- This is used to locate each separator character
declare @array_value varchar(100) -- this holds each array value as it is returned

set @ProductionTypes = @ProductionTypes + @separator
while patindex('%' + @separator + '%' , @ProductionTypes) <> 0 -- Loop through the string searching for separtor characters
begin
select @separator_position = patindex('%' + @separator + '%' , @ProductionTypes) -- patindex matches the a pattern against a string
select @array_value = left(@ProductionTypes, @separator_position - 1)
insert into @ProductionTypesTable (ProductionTypeID) values (@array_value)
select @ProductionTypes = stuff(@ProductionTypes, 1, @separator_position, '') -- This replaces what we just processed with and empty string
end
set nocount off

END



SELECT tblEntry.EntryID, EntryName , Town, County, Postcode
FROM tblEntry
INNER JOIN
WHERE
(@Name is null OR CONTAINS(tblEntry.*, @Name)) -- name
AND
(@ProductionTypes is null OR
or tblEntry.EntryID in (select EntryID from @ProductionTypesTable as types inner join tblEntryProductionTypes on types.ProductionTypeID =tblEntryProductionTypes.ProductionTypeID)
)
ORDER BY PaidEntry DESC, EntrySortName

END


Thanks,

Nick...

rahul8346
Starting Member

21 Posts

Posted - 2006-05-12 : 08:23:05
Hi, I am a Newbie but i feels if make the list table index clustered it will reduce your execution time...
Go to Top of Page

mmarovic
Aged Yak Warrior

518 Posts

Posted - 2006-05-12 : 09:27:49
http://www.sql-server-performance.com/mm_list_random_values.asp

http://www.sommarskog.se/arrays-in-sql.html

Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2006-05-12 : 12:23:46
Your problem is the "-- Loop through the string searching for separtor characters"

Have a look at using a SPLIT function. This can take a delimited list and "split" it into a temporary table, which you can then join back (or us an IN test). The trick is that the SPLIT function will use set-based methods, rather than loop-based, and so will be much faster.

See http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=55210&SearchTerms=CSV,Splitting%20delimited%20lists,Best%20split%20functions

Kristen
Go to Top of Page

nmg196
Yak Posting Veteran

70 Posts

Posted - 2006-05-12 : 12:36:30
I don't think the problem is with turning an 8 character string into a table - that bit happens in a couple of milliseconds. I think the problem lies with the way it does the join, but I can't figure out why that makes it so slow. It can't be spending 24 seconds splitting the string.
Go to Top of Page

Kristen
Test

22859 Posts

Posted - 2006-05-12 : 13:11:31
Well, I'd still use a SPLIT function, but you may be right.

You could stick a few:

SELECT @SplitTime1 = GetDate()
...
SELECT @SplitTime2 = GetDate()
...

then at the bottom:

SELECT [@SplitTime1]=@SplitTime1, [@SplitTime2]=@SplitTime2, ...

I always put PKs on tempTables, because I've found that they can be slow without, YMMV

declare @ProductionTypesTable TABLE
(
ProductionTypeID int,
PRIMARY KEY
(
ProductionTypeID
)
)

I have no idea whether "CONTAINS(tblEntry.*, @Name))" is fast or slow - you might like to try a run with that removed and see what the run time is.

It might also be worth doing some individual queries to TempTable, and "merging them", rather than having the particular combination of OR and AND in your query - the optimiser is probably missing all sorts of opportunities!

Kristen
Go to Top of Page

rahul8346
Starting Member

21 Posts

Posted - 2006-05-13 : 02:25:34
This is a very open ended question and there could be a lot of reasons behind the poor performance of a query. But some general issues that you could see about would be: No indexes, table scans, missing or out of date statistics, blocking, excess recompilations of stored procedures, procedures and triggers without SET NOCOUNT ON, poorly written query with unnecessarily complicated joins, too much normalization, excess usage of cursors and temporary tables.

Some of the tools/ways that help you troubleshooting performance problems are: SET SHOWPLAN_ALL ON, SET SHOWPLAN_TEXT ON, SET STATISTICS IO ON, SQL Server Profiler, Windows NT /2000 Performance monitor, Graphical execution plan in Query Analyzer.

You can go through the white paper on performance tuning SQL Server from Microsoft web site. You can also check out www.sql-server-performance.com

Go to Top of Page

RyanRandall
Master Smack Fu Yak Hacker

1074 Posts

Posted - 2006-05-15 : 08:01:27
I agree with rahul8346. Here are a couple of links which might help you (start to) learn how to work through the optimisation yourself...

http://www.sqlservercentral.com/columnists/jsack/sevenshowplanredflags.asp
http://www.sql-server-performance.com/query_execution_plan_analysis.asp


Ryan Randall
www.monsoonmalabar.com London-based IT consultancy

Solutions are easy. Understanding the problem, now, that's the hard part.
Go to Top of Page
   

- Advertisement -