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.
| Author |
Topic |
|
staplebottom
Starting Member
29 Posts |
Posted - 2007-12-17 : 14:54:24
|
Hi,I need to speed up this query which uses a recursive query to check if a category is a child category of another category. It takes too long to run and Im wondering if there is anything anyone can advise.-- SP to select Job Profiles For ListALTER PROCEDURE [dbo].[uspf_JobProfiles_selectJobProfilesByCountryID]( @CountryID as INT)AS DECLARE @cID int, @pID int DECLARE @RowNum int CREATE Table #jpt ( id int, categoryID int, baseCategoryID int, profileTitle nvarchar(255), profileShowCompany bit, profileCompanyName nvarchar(255), profileCountryID int, profileRating int, profileOverview nvarchar(max), imageName nvarchar(255), imageCaption nvarchar(4000), username nvarchar(255) ) -- Select Base Cateories (Parentid = 0) DECLARE base_cat CURSOR FOR Select lut_category.CategoryId, lut_category_parents.ParentId from lut_category,lut_category_parents WHERE (lut_category.CategoryID = lut_Category_parents.CategoryID) AND (lut_category_parents.ParentId = 0) AND (lut_category.enabled = 1) OPEN base_cat FETCH NEXT FROM base_cat INTO @cID, @pID SET @RowNum = 0 WHILE @@FETCH_STATUS = 0 BEGIN -- For every base category I want to get job profiles which exist in sub categories. As there are multiple levels of categories I need to use a recursive function. --Recursive Bit WITH subCats(categoryID) AS ( SELECT lcp.categoryID FROM lut_category_parents AS lcp WHERE lcp.parentid = @cID UNION ALL SELECT lcp2.categoryID FROM lut_category_parents AS lcp2 INNER JOIN subCats AS sc ON lcp2.parentID = sc.CategoryID ) --Insert into Results Table INSERT INTO #jpt (id, categoryID, baseCategoryID, profileTitle, profileShowCompany, profileCompanyName, profileCountryID, profileRating, profileOverview, imageName, imageCaption, username) SELECT tjp.id, tjp.categoryID, @cID as baseCategoryID, tjp.profileTitle, tjp.profileShowCompany, tjp.profileCompanyName, tjp.profileCountryID, tjp.profileRating, tjp.profileOverview, tjpi.imageName, tjpi.imageCaption, au.username FROM [dbo].[tbl_jobprofile] tjp left outer Join dbo.tbl_jobprofile_images tjpi ON tjpi.profileID = tjp.id AND tjpi.imageType='Overview' left outer join dbo.aspnet_Users au ON au.userid = tjp.userid WHERE tjp.profileCountryID = @countryID AND tjp.active = 1 AND tjp.enabled=1 AND tjp.categoryID in (SELECT categoryID FROM subCats AS sc) ORDER by tjp.profileTitle FETCH NEXT FROM base_cat INTO @cID, @pID END CLOSE base_cat DEALLOCATE base_catSELECT * fROM #jpt DROP table #jpt |
|
|
JasonL
Starting Member
35 Posts |
Posted - 2007-12-17 : 15:22:52
|
| Assuming all your tables/indexes are normalized and indexed properly On first look :... AND tjp.categoryID in (SELECT categoryID FROM subCats AS sc)could be the problem if "subCats" is a huge table -- full table scan?)Tried using the profiler yet? http://msdn2.microsoft.com/en-us/library/ms181091.aspx(This is my quick 3 minutes assessment, sorry could only guess what the potential problem is without knowing you data structure and the actual logic of the code)JasonL -- http://blogs.msdn.com/usisvde/ |
 |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2007-12-17 : 15:28:16
|
| do a forum search (on this site) for: "trees hierarchies"There are many solutions discussed.There is also at least a couple articles written her on the topic as well.Be One with the OptimizerTG |
 |
|
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2007-12-17 : 15:32:01
|
Obviously, I didn't test this, but I *think* you can do this is one query: WITH subCats(categoryID) AS ( SELECT lcp.categoryID FROM lut_category_parents AS lcp WHERE lcp.parentid = @cID UNION ALL SELECT lcp2.categoryID FROM lut_category_parents AS lcp2 INNER JOIN subCats AS sc ON lcp2.parentID = sc.CategoryID )INSERT INTO #jpt (id, categoryID, baseCategoryID, profileTitle, profileShowCompany, profileCompanyName, profileCountryID, profileRating, profileOverview, imageName, imageCaption, username)SELECT tjp.id, tjp.categoryID, @cID as baseCategoryID, tjp.profileTitle, tjp.profileShowCompany, tjp.profileCompanyName, tjp.profileCountryID, tjp.profileRating, tjp.profileOverview, tjpi.imageName, tjpi.imageCaption, au.usernameFROM [dbo].[tbl_jobprofile] AS tjp INNER JOIN subCats ON tjp.categoryID = subCats.categoryIDINNER JOIN ( Select lut_category.CategoryId from lut_category,lut_category_parents WHERE (lut_category.CategoryID = lut_Category_parents.CategoryID) AND (lut_category_parents.ParentId = 0) AND (lut_category.enabled = 1) ) AS temp ON tjp.profileCountryID = tem.CategoryIdLEFT OUTER JOIN dbo.tbl_jobprofile_images AS tjpi ON tjpi.profileID = tjp.id AND tjpi.imageType='Overview'LEFT OUTER JOIN dbo.aspnet_Users AS au ON au.userid = tjp.useridWHERE tjp.active = 1 AND tjp.enabled=1ORDER BY tjp.profileTitle |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-12-17 : 15:40:42
|
[code]ALTER PROCEDURE dbo.uspf_JobProfiles_selectJobProfilesByCountryID( @CountryID INT)ASSET NOCOUNT ON;WITH subCats(categoryID) AS( SELECT c.CategoryId FROM lut_category AS c INNER JOIN lut_category_parents AS p ON p.CategoryID = c.CategoryID WHERE p.ParentId = 0 AND c.enabled = 1 UNION ALL SELECT lcp2.categoryID FROM lut_category_parents AS lcp2 INNER JOIN subCats AS sc ON sc.CategoryID = lcp2.parentID)SELECT tjp.id, tjp.categoryID, sc.CategoryID as baseCategoryID, tjp.profileTitle, tjp.profileShowCompany, tjp.profileCompanyName, tjp.profileCountryID, tjp.profileRating, tjp.profileOverview, tjpi.imageName, tjpi.imageCaption, au.usernameFROM [dbo].[tbl_jobprofile] as tjp LEFT JOIN dbo.tbl_jobprofile_images as tjpi ON tjpi.profileID = tjp.id AND tjpi.imageType = 'Overview'LEFT JOIN dbo.aspnet_Users as au ON au.userid = tjp.useridINNER JOIN SubCats AS sc ON sc.categoryID = tjp.categoryID)WHERE tjp.profileCountryID = @countryID AND tjp.active = 1 AND tjp.enabled=1ORDER BY sc.CategoryID, tjp.profileTitle[/code] E 12°55'05.25"N 56°04'39.16" |
 |
|
|
|
|
|
|
|