September 1, 2007 at 6:25 am
I have lots of reports in which there are many fields that are used in dynamic WHERE clause with dynamic sort (ORDER BY field with asc or desc). Following are fields defined in user interface to put required criteria:
1- FirstName
2- LastName
3- FromDade
4- ToDate
5- Department
6- Subject
7- Topic
8- Location
9- StudentID (i.e. Loc+Dept+FirstName+LastName)= 25 characters
To identify every student from where location he/she belonging.
FirstName / LastName
May be ‘deborah’ or ‘de’ so all starting with firstName (LIKE or =) ‘deborah’ or ‘de%’ may appear in WHERE clause. If there is no input it should not use FirstName in WHERE clause. Same with Last name. it might be combination of both FirstName and Last Name for example Deborah M%. all names should match with user criteria.
FromDate / ToDate
Same like above criteria, usually we can mostly use FromDate and toDate and calculate from User Interface to force its expected to receive these two parameters at-least. But if not given, like above example, User want to see all Trainings session for those whose only first Name is Deborah. That’s it. So it may search without FromDate and ToDate.
Location --> Department --> Subject -- > Topic
It is possible for user to input criteria with or without hierarchy like given above. User can select only Location and or Department and or subject and or Topic.
These all fields are defined in user interface to search anything (combination of any fields).
There are more than 6 tables require JOIN to get summarized Training LOG information.
I already have millions of trainings sessions (history of each training attended by students) in my Training Log history. And there are above 85 thousands of students in STUDENT Table.
I have recently joined this organization and I have to fix the performance issue on priority bases because these reports sometimes does not return results and went down – need to reopen browser. Few reports estimate they comes in 20 minutes time approximately.
The organization is joining with another one and they expect Students that require training would be 100 of thousands of new Students joining this database.
Following were my first suggestions to fix the problem.
1- Put indexing in where clause
2- Extend server (processor and RAM) that will not be approved till we all migrate our web application on .NET 2.0- that aleast takes 6 to 9 months.
3- Check stored procedures for better performance gain. Right - the application is using stored procedures for all reportings.
4- And all of you guru’s suggestions from this forum.
I would like to know how others guys face such scenario and gain performance in results with given resources only.
If there is any question, let me know.
September 1, 2007 at 12:18 pm
The problem is likely not the Dynamic SQL... nor is it likely the fact that you are joining 6 tables... but it's real hard to figure out what it could be without you posting the offending code and the DDL that creates the related tables.
--Jeff Moden
Change is inevitable... Change for the better is not.
September 3, 2007 at 4:27 am
Thanks Jeff for your reply and taking interest in my problem.
Well, I won’t give you exact scenario according to existing database/nature of business. But I can give you an example to work around as follow:
List of Tables involved.
Students
- StudentID varchar (as I mentioned above how it is generatred)
- FirstName varchar
- LastName varchar
Locations
- LocationID tinyint
- LocationName varchar
Subnets
- SubnetID int
- Subnet varchar
- LocationID tinyint
Departments
- DepartmentID int
- DepartmentName varchar
- SubnetID tinyint
Subjects
- SubjectID int
- SubjectName varchar
- DepartmentID int
Topics
- TopicID int
- TopicName varchar
- SubjectID int
TrackerLog
- TrakcerLogID int (Training Session ID)
- SessionStart DateTime
- SessionEnd DateTime
- StudentID int
- TopicID int
- IP varchar
- And many otherFields Like user completed this session or NOT
Schedules
- ScheduleID int
- TrainingStart DateTime
- TrainingEnd DateTime
We have usually schedules, TrackingLog and User machine IP that is checked in Subnet Table to see from which location user belongs and saved in TrackerLog and the main source of information from where we get scores for students. This training is based on sessionStart and SessionEnd and the students score is updated per Topic.
I hope, now you will get a better idea about the scenario and requirements. These reports are basically used to evaluate students grade according to their participation per schedule. or how much a Topics was browsed mostly. Most wanted topics, locations, subjects, Locations, departments. at what time mostly users hit TrackerLog during 24 hrs. and so many other queries.
I just want a simple solution how to face such condition if someone has done any related task may share his/her experience, I need some hints that which technique should we use in this situation.
Shamshad Ali.
September 3, 2007 at 6:51 am
Could you post one of the offending queries please, as well as the existing indexes on the tables.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
September 3, 2007 at 4:17 pm
Shamshad,
You forgot to include the offending code like I asked...
--Jeff Moden
Change is inevitable... Change for the better is not.
September 3, 2007 at 11:06 pm
In short I'm sending you a sp similar (tables and fileds are changed) like below:
ALTER PROCEDURE [dbo].[SP_caller_Usage]
-- SP_Caller_Usage @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=2, @SortType ='desc', @GroupLevel=1 -- (95358) in 1:16/18 (Administration)
-- SP_Caller_Usage @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=7, @SortType ='desc', @GroupLevel=2 -- (95887) in 1:24/22 (Region)
-- SP_Caller_Usage @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=7, @SortType ='desc', @GroupLevel=3 -- (97062) in 1:32/28 (Facility)
-- SP_Caller_Usage @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=5, @SortType ='desc', @GroupLevel=4 -- (95271) in 1:10/15 (Department)
-- SP_Caller_Usage @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=5, @SortType ='desc', @GroupLevel=5 -- (3) in 0:49 (Administration)
-- SP_Caller_Usage @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=5, @SortType ='desc', @GroupLevel=6 -- (34) in 1:22 (Region)
-- SP_Caller_Usage @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=5, @SortType ='desc', @GroupLevel=7 -- (216) in 1:42 (Facility)
-- SP_Caller_Usage @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=5, @SortType ='desc', @GroupLevel=8 -- (1) in 0:37 (Department)
-- SP_Caller_Usage @ToDate='12-Jul-2007', @FromDate=NULL, @Last_Name='', @First_Name ='', @Login_ID ='', @Administration_id =0, @Region_ID =0, @Facility_Id =0, @sort = 2, @SortType='desc', @GroupLevel =1
-- (95389) in 3:40 (Administration) - done
-- SP_Caller_Usage @ToDate='12-Jul-2007', @FromDate=NULL, @Last_Name='', @First_Name ='', @Login_ID ='', @Administration_id =0, @Region_ID =0, @Facility_Id =0, @sort = 7, @SortType='desc', @GroupLevel =2
-- (95918) in 4:00 (Region) - done
-- SP_Caller_Usage @ToDate='12-Jul-2007', @FromDate=NULL, @Last_Name='', @First_Name ='', @Login_ID ='', @Administration_id =0, @Region_ID =0, @Facility_Id =0, @sort = 7, @SortType='desc', @GroupLevel =3
-- (97093) in 4:25 (Facility) - done
-- SP_Caller_Usage @ToDate='12-Jul-2007', @FromDate=NULL, @Last_Name='', @First_Name ='', @Login_ID ='', @Administration_id =0, @Region_ID =0, @Facility_Id =0, @sort = 5, @SortType='desc', @GroupLevel =4
-- (95303) in 3:02 (Department) - done
-- SP_Caller_Usage @ToDate='12-Jul-2007', @FromDate=NULL, @Last_Name='', @First_Name ='', @Login_ID ='', @Administration_id =0, @Region_ID =0, @Facility_Id =0, @sort = 5, @SortType='desc', @GroupLevel =5
-- (3) in 0:43 (Administration) - done
-- SP_Caller_Usage @ToDate='12-Jul-2007', @FromDate=NULL, @Last_Name='', @First_Name ='', @Login_ID ='', @Administration_id =0, @Region_ID =0, @Facility_Id =0, @sort = 5, @SortType='desc', @GroupLevel =6
-- (34) in 1:15 (Region) - done
-- SP_Caller_Usage @ToDate='12-Jul-2007', @FromDate=NULL, @Last_Name='', @First_Name ='', @Login_ID ='', @Administration_id =0, @Region_ID =0, @Facility_Id =0, @sort = 5, @SortType='desc', @GroupLevel =7
-- (216) in 1:33 (Facility)
-- SP_Caller_Usage @ToDate='12-Jul-2007', @FromDate=NULL, @Last_Name='', @First_Name ='', @Login_ID ='', @Administration_id =0, @Region_ID =0, @Facility_Id =0, @sort = 5, @SortType='desc', @GroupLevel =8
-- (1) in 0:22 (Department) - done
@ToDate datetime ,
@FromDate datetime ,
@Last_Name varchar(100)=NULL,
@First_Name varchar(100)=NULL,
@Login_ID varchar(100)=NULL,
@Administration_id smallint=0,
@Region_ID smallint=0,
@Facility_Id smallint=0,
@sort smallint=6,
@SortType varchar(10)='DESC',
@GroupLevel smallint = 1
AS
BEGIN
SET NOCOUNT ON
set @First_Name = case @First_Name when '' then Null else @First_Name end
set @Last_Name = case @Last_Name when '' then Null else @Last_Name end
SET @Login_ID = case @Login_ID when '' then Null else @Login_ID end
set @Administration_id = case @Administration_id when 0 then Null else @Administration_id end
set @Region_ID = case @Region_ID when 0 then Null else @Region_ID end
set @Facility_Id = case @Facility_Id when 0 then Null else @Facility_Id end
---------------------------------------- Group by Administration WHEN @GroupLevel = 1
IF @GroupLevel = 1
BEGIN
SELECT m.Login_ID,
m.Administration,
sum(isnull(l.Lib_Visits,0)) as Lib_Visits,
sum(isnull(l.Lib_Completed,0)) as Lib_Completed,
sum(isnull(c.Channel_Visits,0)) as Channel_Visits,
sum(isnull(c.Ch_Prog_Completed,0)) as Ch_Prog_Completed,
sum(isnull(l.Lib_Visits,0)) + sum(isnull(c.Channel_Visits,0)) as tot_Visits,
sum(isnull(l.Lib_Completed,0)) + sum(isnull(c.Ch_Prog_Completed,0)) as tot_Completed,
cv.First_name + ' ' + cv.Last_name as Login_Name,
cv.First_name,
cv.Last_name,
cv.Department,
cv.Guest,
m.Login_ID as [User_ID],
m.Login_Type,
m.Guest_ID AS Guest_Exist
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
LEFT OUTER JOIN tbl_cv_user cv ON m.Login_ID = cv.cv_user_name
where
m.Login_Name LIKE COALESCE(@First_Name + '%', Login_Name)-- 105101 in 55 Sec.
AND m.Login_Name LIKE COALESCE('%' + ' ' + @Last_Name + '%', Login_Name)
AND m.Login_ID LIKE COALESCE(@Login_ID + '%', Login_ID)
AND m.Administration_ID BETWEEN COALESCE(@Administration_id, Administration_ID) AND COALESCE(@Administration_id, Administration_ID)
AND m.Region_ID BETWEEN COALESCE(@Region_ID, Region_ID) AND COALESCE(@Region_ID, Region_ID)
AND m.Facility_ID BETWEEN COALESCE(@Facility_ID, m.Facility_ID) AND COALESCE(@Facility_ID, m.Facility_ID)
AND m.Start_DateTime BETWEEN COALESCE(@FromDate, m.Start_DateTime) AND COALESCE(@ToDate, m.Start_DateTime)
AND cv.First_Name is not null
AND cv.First_Name LIKE COALESCE(@First_Name + '%', cv.First_Name)
AND cv.Last_Name LIKE COALESCE('%' + Replace(@Last_Name,' ','') + '%', cv.Last_Name)
GROUP BY
m.Login_ID,
m.Administration,
m.Login_Type,
m.Guest_ID,
cv.First_name,
cv.Last_name,
cv.Department,
cv.Guest
having
sum(isnull(l.Lib_Visits,0)) >0 or
sum(isnull(l.Lib_Completed,0)) >0 or
sum(isnull(c.Channel_Visits,0)) >0 or
sum(isnull(c.Ch_Prog_Completed,0)) >0
-- order by Lib_Visits desc
-- order by Channel_Visits desc
ORDER BY
CASE lower(@SortType)
WHEN 'desc' THEN
CASE @sort
WHEN 1 THEN Login_Id
WHEN 2 THEN Administration
WHEN 9 THEN Login_ID
WHEN 10 THEN Department
WHEN 11 THEN Guest_ID
END
END
DESC,
CASE lower(@SortType)
WHEN 'desc' THEN
CASE @sort
WHEN 5 THEN sum(isnull(c.Channel_Visits,0))
WHEN 6 THEN sum(isnull(l.Lib_Visits,0))
WHEN 7 THEN sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0))
WHEN 8 THEN sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0))
END
END
DESC,
CASE lower(@SortType)
WHEN 'asc' THEN
CASE @sort
WHEN 1 THEN Login_Id
WHEN 2 THEN Administration
WHEN 9 THEN Login_ID
WHEN 10 THEN Department
WHEN 11 THEN Guest_ID
END
END,
CASE lower(@SortType)
WHEN 'asc' THEN
CASE @sort
WHEN 5 THEN sum(isnull(c.Channel_Visits,0))
WHEN 6 THEN sum(isnull(l.Lib_Visits,0))
WHEN 7 THEN sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0))
WHEN 8 THEN sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0))
END
END
END
---------------------------------------- Group by Region WHEN @GroupLevel = 2
IF @GroupLevel = 2
BEGIN
SELECT m.Login_ID,
m.Administration,
m.Region,
sum(isnull(l.Lib_Visits,0)) as Lib_Visits,
sum(isnull(l.Lib_Completed,0)) as Lib_Completed,
sum(isnull(c.Channel_Visits,0)) as Channel_Visits,
sum(isnull(c.Ch_Prog_Completed,0)) as Ch_Prog_Completed,
sum(isnull(l.Lib_Visits,0)) + sum(isnull(c.Channel_Visits,0)) as tot_Visits,
sum(isnull(l.Lib_Completed,0)) + sum(isnull(c.Ch_Prog_Completed,0)) as tot_Completed,
cv.First_name + ' ' + cv.Last_name as Login_Name,
cv.First_name,
cv.Last_name,
cv.Department,
cv.Guest,
m.Login_ID as [User_ID],
m.Login_Type,
m.Guest_ID AS Guest_Exist
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
LEFT OUTER JOIN tbl_cv_user cv ON m.Login_ID = cv.cv_user_name
where
m.Login_Name LIKE COALESCE(@First_Name + '%', Login_Name)-- 105101 in 55 Sec.
AND m.Login_Name LIKE COALESCE('%' + ' ' + @Last_Name + '%', Login_Name)
AND m.Login_ID LIKE COALESCE(@Login_ID + '%', Login_ID)
AND m.Administration_ID BETWEEN COALESCE(@Administration_id, Administration_ID) AND COALESCE(@Administration_id, Administration_ID)
AND m.Region_ID BETWEEN COALESCE(@Region_ID, Region_ID) AND COALESCE(@Region_ID, Region_ID)
AND m.Facility_ID BETWEEN COALESCE(@Facility_ID, m.Facility_ID) AND COALESCE(@Facility_ID, m.Facility_ID)
AND m.Start_DateTime BETWEEN COALESCE(@FromDate, m.Start_DateTime) AND COALESCE(@ToDate, m.Start_DateTime)
AND cv.First_Name is not null
AND cv.First_Name LIKE COALESCE(@First_Name + '%', cv.First_Name)
AND cv.Last_Name LIKE COALESCE('%' + Replace(@Last_Name,' ','') + '%', cv.Last_Name)
GROUP BY
m.Login_ID,
m.Administration,
m.Region,
m.Login_Type,
m.Guest_ID,
cv.First_name,
cv.Last_name,
cv.Department,
cv.Guest
having
sum(isnull(l.Lib_Visits,0)) >0 or
sum(isnull(l.Lib_Completed,0)) >0 or
sum(isnull(c.Channel_Visits,0)) >0 or
sum(isnull(c.Ch_Prog_Completed,0)) >0
ORDER BY
CASE lower(@SortType)
WHEN 'desc' THEN
CASE @sort
WHEN 1 THEN Login_Id
WHEN 2 THEN Administration
WHEN 3 THEN Region
WHEN 9 THEN Login_ID
WHEN 10 THEN Department
WHEN 11 THEN Guest_ID
END
END
DESC,
CASE lower(@SortType)
WHEN 'desc' THEN
CASE @sort
WHEN 5 THEN sum(isnull(c.Channel_Visits,0))
WHEN 6 THEN sum(isnull(l.Lib_Visits,0))
WHEN 7 THEN sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0))
WHEN 8 THEN sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0))
END
END
DESC,
CASE lower(@SortType)
WHEN 'asc' THEN
CASE @sort
WHEN 1 THEN Login_Id
WHEN 2 THEN Administration
WHEN 3 THEN Region
WHEN 9 THEN Login_ID
WHEN 10 THEN Department
WHEN 11 THEN Guest_ID
END
END,
CASE lower(@SortType)
WHEN 'asc' THEN
CASE @sort
WHEN 5 THEN sum(isnull(c.Channel_Visits,0))
WHEN 6 THEN sum(isnull(l.Lib_Visits,0))
WHEN 7 THEN sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0))
WHEN 8 THEN sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0))
END
END
END
---------------------------------------- Group by Facility WHEN @GroupLevel = 3
IF @GroupLevel = 3
BEGIN
SET NOCOUNT ON
SELECT m.Login_ID,
m.Administration,
m.Region,
m.Facility,
sum(isnull(l.Lib_Visits,0)) as Lib_Visits,
sum(isnull(l.Lib_Completed,0)) as Lib_Completed,
sum(isnull(c.Channel_Visits,0)) as Channel_Visits,
sum(isnull(c.Ch_Prog_Completed,0)) as Ch_Prog_Completed,
sum(isnull(l.Lib_Visits,0)) + sum(isnull(c.Channel_Visits,0)) as tot_Visits,
sum(isnull(l.Lib_Completed,0)) + sum(isnull(c.Ch_Prog_Completed,0)) as tot_Completed,
cv.First_name + ' ' + cv.Last_name as Login_Name,
cv.First_name,
cv.Last_name,
cv.Department,
cv.Guest,
m.Login_ID as [User_ID],
m.Login_Type,
m.Guest_ID AS Guest_Exist
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
LEFT OUTER JOIN tbl_cv_user cv ON m.Login_ID = cv.cv_user_name
where
m.Login_Name LIKE COALESCE(@First_Name + '%', Login_Name)-- 105101 in 55 Sec.
AND m.Login_Name LIKE COALESCE('%' + ' ' + @Last_Name + '%', Login_Name)
AND m.Login_ID LIKE COALESCE(@Login_ID + '%', Login_ID)
AND m.Administration_ID BETWEEN COALESCE(@Administration_id, Administration_ID) AND COALESCE(@Administration_id, Administration_ID)
AND m.Region_ID BETWEEN COALESCE(@Region_ID, Region_ID) AND COALESCE(@Region_ID, Region_ID)
AND m.Facility_ID BETWEEN COALESCE(@Facility_ID, m.Facility_ID) AND COALESCE(@Facility_ID, m.Facility_ID)
AND m.Start_DateTime BETWEEN COALESCE(@FromDate, m.Start_DateTime) AND COALESCE(@ToDate, m.Start_DateTime)
AND cv.First_Name is not null
AND cv.First_Name LIKE COALESCE(@First_Name + '%', cv.First_Name)
AND cv.Last_Name LIKE COALESCE('%' + Replace(@Last_Name,' ','') + '%', cv.Last_Name)
GROUP BY
m.Login_ID,
m.Administration,
m.Region,
m.Facility,
m.Login_Type,
m.Guest_ID,
cv.First_name,
cv.Last_name,
cv.Department,
cv.Guest
having
sum(isnull(l.Lib_Visits,0)) >0 or
sum(isnull(l.Lib_Completed,0)) >0 or
sum(isnull(c.Channel_Visits,0)) >0 or
sum(isnull(c.Ch_Prog_Completed,0)) >0
ORDER BY
CASE lower(@SortType)
WHEN 'desc' THEN
CASE @sort
WHEN 1 THEN Login_Id
WHEN 2 THEN Administration
WHEN 3 THEN Region
WHEN 4 THEN Facility
WHEN 9 THEN Login_ID
WHEN 10 THEN Department
WHEN 11 THEN Guest_ID
END
END
DESC,
CASE lower(@SortType)
WHEN 'desc' THEN
CASE @sort
WHEN 5 THEN sum(isnull(c.Channel_Visits,0))
WHEN 6 THEN sum(isnull(l.Lib_Visits,0))
WHEN 7 THEN sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0))
WHEN 8 THEN sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0))
END
END
DESC,
CASE lower(@SortType)
WHEN 'asc' THEN
CASE @sort
WHEN 1 THEN Login_Id
WHEN 2 THEN Administration
WHEN 3 THEN Region
WHEN 4 THEN Facility
WHEN 9 THEN Login_ID
WHEN 10 THEN Department
WHEN 11 THEN Guest_ID
END
END,
CASE lower(@SortType)
WHEN 'asc' THEN
CASE @sort
WHEN 5 THEN sum(isnull(c.Channel_Visits,0))
WHEN 6 THEN sum(isnull(l.Lib_Visits,0))
WHEN 7 THEN sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0))
WHEN 8 THEN sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0))
END
END
END
---------------------------------------- Group by Department WHEN @GroupLevel = 4
IF @GroupLevel = 4
BEGIN
SELECT m.Login_ID,
sum(isnull(l.Lib_Visits,0)) as Lib_Visits,
sum(isnull(l.Lib_Completed,0)) as Lib_Completed,
sum(isnull(c.Channel_Visits,0)) as Channel_Visits,
sum(isnull(c.Ch_Prog_Completed,0)) as Ch_Prog_Completed,
sum(isnull(l.Lib_Visits,0)) + sum(isnull(c.Channel_Visits,0)) as tot_Visits,
sum(isnull(l.Lib_Completed,0)) + sum(isnull(c.Ch_Prog_Completed,0)) as tot_Completed,
cv.First_name + ' ' + cv.Last_name as Login_Name,
cv.First_name,
cv.Last_name,
cv.Department,
cv.Guest,
m.Login_ID as [User_ID],
m.Login_Type,
m.Guest_ID AS Guest_Exist
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
LEFT OUTER JOIN tbl_cv_user cv ON m.Login_ID = cv.cv_user_name
where
m.Login_Name LIKE COALESCE(@First_Name + '%', Login_Name)-- 105101 in 55 Sec.
AND m.Login_Name LIKE COALESCE('%' + ' ' + @Last_Name + '%', Login_Name)
AND m.Login_ID LIKE COALESCE(@Login_ID + '%', Login_ID)
AND m.Administration_ID BETWEEN COALESCE(@Administration_id, Administration_ID) AND COALESCE(@Administration_id, Administration_ID)
AND m.Region_ID BETWEEN COALESCE(@Region_ID, Region_ID) AND COALESCE(@Region_ID, Region_ID)
AND m.Facility_ID BETWEEN COALESCE(@Facility_ID, m.Facility_ID) AND COALESCE(@Facility_ID, m.Facility_ID)
AND m.Start_DateTime BETWEEN COALESCE(@FromDate, m.Start_DateTime) AND COALESCE(@ToDate, m.Start_DateTime)
AND cv.First_Name is not null
AND cv.First_Name LIKE COALESCE(@First_Name + '%', cv.First_Name)
AND cv.Last_Name LIKE COALESCE('%' + Replace(@Last_Name,' ','') + '%', cv.Last_Name)
GROUP BY
m.Login_ID,
m.Login_Type,
m.Guest_ID,
cv.First_name,
cv.Last_name,
cv.Department,
cv.Guest
having
sum(isnull(l.Lib_Visits,0)) >0 or
sum(isnull(l.Lib_Completed,0)) >0 or
sum(isnull(c.Channel_Visits,0)) >0 or
sum(isnull(c.Ch_Prog_Completed,0)) >0
ORDER BY
CASE lower(@SortType)
WHEN 'desc' THEN
CASE @sort
WHEN 1 THEN Login_Id
WHEN 9 THEN Login_ID
WHEN 10 THEN Department
WHEN 11 THEN Guest_ID
END
END
DESC,
CASE lower(@SortType)
WHEN 'desc' THEN
CASE @sort
WHEN 5 THEN sum(isnull(c.Channel_Visits,0))
WHEN 6 THEN sum(isnull(l.Lib_Visits,0))
WHEN 7 THEN sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0))
WHEN 8 THEN sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0))
END
END
DESC,
CASE lower(@SortType)
WHEN 'asc' THEN
CASE @sort
WHEN 1 THEN Login_Id
WHEN 9 THEN Login_ID
WHEN 10 THEN Department
WHEN 11 THEN Guest_ID
END
END,
CASE lower(@SortType)
WHEN 'asc' THEN
CASE @sort
WHEN 5 THEN sum(isnull(c.Channel_Visits,0))
WHEN 6 THEN sum(isnull(l.Lib_Visits,0))
WHEN 7 THEN sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0))
WHEN 8 THEN sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0))
END
END
END
---------------------------------------- Group by Administration Without UserInfo WHEN @GroupLevel = 5
IF @GroupLevel = 5
BEGIN
SELECT m.Administration_ID,
Administration,
sum(isnull(l.Lib_Visits,0)) as Lib_Visits,
sum(isnull(l.Lib_Completed,0)) as Lib_Completed,
sum(isnull(c.Channel_Visits,0)) as Channel_Visits,
sum(isnull(c.Ch_Prog_Completed,0)) as Ch_Prog_Completed,
sum(isnull(l.Lib_Visits,0)) + sum(isnull(c.Channel_Visits,0)) as tot_Visits,
sum(isnull(l.Lib_Completed,0)) + sum(isnull(c.Ch_Prog_Completed,0)) as tot_Completed
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
where
m.Login_Name LIKE COALESCE(@First_Name + '%', Login_Name)-- 105101 in 55 Sec.
AND m.Login_Name LIKE COALESCE('%' + ' ' + @Last_Name + '%', Login_Name)
AND m.Login_ID LIKE COALESCE(@Login_ID + '%', Login_ID)
AND m.Administration_ID BETWEEN COALESCE(@Administration_id, Administration_ID) AND COALESCE(@Administration_id, Administration_ID)
AND m.Region_ID BETWEEN COALESCE(@Region_ID, Region_ID) AND COALESCE(@Region_ID, Region_ID)
AND m.Facility_ID BETWEEN COALESCE(@Facility_ID, m.Facility_ID) AND COALESCE(@Facility_ID, m.Facility_ID)
AND m.Start_DateTime BETWEEN COALESCE(@FromDate, m.Start_DateTime) AND COALESCE(@ToDate, m.Start_DateTime)
GROUP BY
m.Administration_ID,
Administration
having
sum(isnull(l.Lib_Visits,0)) >0 or
sum(isnull(l.Lib_Completed,0)) >0 or
sum(isnull(c.Channel_Visits,0)) >0 or
sum(isnull(c.Ch_Prog_Completed,0)) >0
ORDER BY
CASE lower(@SortType)
WHEN 'desc' THEN
CASE @sort
WHEN 5 THEN sum(isnull(c.Channel_Visits,0))
WHEN 6 THEN sum(isnull(l.Lib_Visits,0))
WHEN 7 THEN sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0))
WHEN 8 THEN sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0))
END
END
DESC,
CASE lower(@SortType)
WHEN 'asc' THEN
CASE @sort
WHEN 5 THEN sum(isnull(c.Channel_Visits,0))
WHEN 6 THEN sum(isnull(l.Lib_Visits,0))
WHEN 7 THEN sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0))
WHEN 8 THEN sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0))
END
END
END
---------------------------------------- Group by Region Without UserInfo WHEN @GroupLevel = 6
IF @GroupLevel = 6
BEGIN
SELECT m.Administration_ID,
Administration,
m.Region_ID,
m.Region,
sum(isnull(l.Lib_Visits,0)) as Lib_Visits,
sum(isnull(l.Lib_Completed,0)) as Lib_Completed,
sum(isnull(c.Channel_Visits,0)) as Channel_Visits,
sum(isnull(c.Ch_Prog_Completed,0)) as Ch_Prog_Completed,
sum(isnull(l.Lib_Visits,0)) + sum(isnull(c.Channel_Visits,0)) as tot_Visits,
sum(isnull(l.Lib_Completed,0)) + sum(isnull(c.Ch_Prog_Completed,0)) as tot_Completed
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
where
m.Login_Name LIKE COALESCE(@First_Name + '%', Login_Name)-- 105101 in 55 Sec.
AND m.Login_Name LIKE COALESCE('%' + ' ' + @Last_Name + '%', Login_Name)
AND m.Login_ID LIKE COALESCE(@Login_ID + '%', Login_ID)
AND m.Administration_ID BETWEEN COALESCE(@Administration_id, Administration_ID) AND COALESCE(@Administration_id, Administration_ID)
AND m.Region_ID BETWEEN COALESCE(@Region_ID, Region_ID) AND COALESCE(@Region_ID, Region_ID)
AND m.Facility_ID BETWEEN COALESCE(@Facility_ID, m.Facility_ID) AND COALESCE(@Facility_ID, m.Facility_ID)
AND m.Start_DateTime BETWEEN COALESCE(@FromDate, m.Start_DateTime) AND COALESCE(@ToDate, m.Start_DateTime)
GROUP BY
m.Administration_ID,
Administration,
m.Region_ID,
m.Region
having
sum(isnull(l.Lib_Visits,0)) >0 or
sum(isnull(l.Lib_Completed,0)) >0 or
sum(isnull(c.Channel_Visits,0)) >0 or
sum(isnull(c.Ch_Prog_Completed,0)) >0
ORDER BY
CASE lower(@SortType)
WHEN 'desc' THEN
CASE @sort
WHEN 5 THEN sum(isnull(c.Channel_Visits,0))
WHEN 6 THEN sum(isnull(l.Lib_Visits,0))
WHEN 7 THEN sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0))
WHEN 8 THEN sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0))
END
END
DESC,
CASE lower(@SortType)
WHEN 'asc' THEN
CASE @sort
WHEN 5 THEN sum(isnull(c.Channel_Visits,0))
WHEN 6 THEN sum(isnull(l.Lib_Visits,0))
WHEN 7 THEN sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0))
WHEN 8 THEN sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0))
END
END
END
---------------------------------------- Group by Facility Without UserInfo WHEN @GroupLevel = 7
IF @GroupLevel = 7
BEGIN
SELECT m.Administration_ID,
Administration,
m.Region_ID,
m.Region,
m.Facility_ID,
m.Facility,
sum(isnull(l.Lib_Visits,0)) as Lib_Visits,
sum(isnull(l.Lib_Completed,0)) as Lib_Completed,
sum(isnull(c.Channel_Visits,0)) as Channel_Visits,
sum(isnull(c.Ch_Prog_Completed,0)) as Ch_Prog_Completed,
sum(isnull(l.Lib_Visits,0)) + sum(isnull(c.Channel_Visits,0)) as tot_Visits,
sum(isnull(l.Lib_Completed,0)) + sum(isnull(c.Ch_Prog_Completed,0)) as tot_Completed
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
where
m.Login_Name LIKE COALESCE(@First_Name + '%', Login_Name)-- 105101 in 55 Sec.
AND m.Login_Name LIKE COALESCE('%' + ' ' + @Last_Name + '%', Login_Name)
AND m.Login_ID LIKE COALESCE(@Login_ID + '%', Login_ID)
AND m.Administration_ID BETWEEN COALESCE(@Administration_id, Administration_ID) AND COALESCE(@Administration_id, Administration_ID)
AND m.Region_ID BETWEEN COALESCE(@Region_ID, Region_ID) AND COALESCE(@Region_ID, Region_ID)
AND m.Facility_ID BETWEEN COALESCE(@Facility_ID, m.Facility_ID) AND COALESCE(@Facility_ID, m.Facility_ID)
AND m.Start_DateTime BETWEEN COALESCE(@FromDate, m.Start_DateTime) AND COALESCE(@ToDate, m.Start_DateTime)
GROUP BY
m.Administration_ID,
Administration,
m.Region_ID,
m.Region,
m.Facility_ID,
m.Facility
having
sum(isnull(l.Lib_Visits,0)) >0 or
sum(isnull(l.Lib_Completed,0)) >0 or
sum(isnull(c.Channel_Visits,0)) >0 or
sum(isnull(c.Ch_Prog_Completed,0)) >0
ORDER BY
CASE lower(@SortType)
WHEN 'desc' THEN
CASE @sort
WHEN 5 THEN sum(isnull(c.Channel_Visits,0))
WHEN 6 THEN sum(isnull(l.Lib_Visits,0))
WHEN 7 THEN sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0))
WHEN 8 THEN sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0))
END
END
DESC,
CASE lower(@SortType)
WHEN 'asc' THEN
CASE @sort
WHEN 5 THEN sum(isnull(c.Channel_Visits,0))
WHEN 6 THEN sum(isnull(l.Lib_Visits,0))
WHEN 7 THEN sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0))
WHEN 8 THEN sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0))
END
END
END
---------------------------------------- Group by Department Without UserInfo WHEN @GroupLevel = 8
IF @GroupLevel = 8
BEGIN
SELECT
sum(isnull(l.Lib_Visits,0)) as Lib_Visits,
sum(isnull(l.Lib_Completed,0)) as Lib_Completed,
sum(isnull(c.Channel_Visits,0)) as Channel_Visits,
sum(isnull(c.Ch_Prog_Completed,0)) as Ch_Prog_Completed,
sum(isnull(l.Lib_Visits,0)) + sum(isnull(c.Channel_Visits,0)) as tot_Visits,
sum(isnull(l.Lib_Completed,0)) + sum(isnull(c.Ch_Prog_Completed,0)) as tot_Completed
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
where
m.Login_Name LIKE COALESCE(@First_Name + '%', Login_Name)-- 105101 in 55 Sec.
AND m.Login_Name LIKE COALESCE('%' + ' ' + @Last_Name + '%', Login_Name)
AND m.Login_ID LIKE COALESCE(@Login_ID + '%', Login_ID)
AND m.Administration_ID BETWEEN COALESCE(@Administration_id, Administration_ID) AND COALESCE(@Administration_id, Administration_ID)
AND m.Region_ID BETWEEN COALESCE(@Region_ID, Region_ID) AND COALESCE(@Region_ID, Region_ID)
AND m.Facility_ID BETWEEN COALESCE(@Facility_ID, m.Facility_ID) AND COALESCE(@Facility_ID, m.Facility_ID)
AND m.Start_DateTime BETWEEN COALESCE(@FromDate, m.Start_DateTime) AND COALESCE(@ToDate, m.Start_DateTime)
having
sum(isnull(l.Lib_Visits,0)) >0 or
sum(isnull(l.Lib_Completed,0)) >0 or
sum(isnull(c.Channel_Visits,0)) >0 or
sum(isnull(c.Ch_Prog_Completed,0)) >0
ORDER BY
CASE lower(@SortType)
WHEN 'desc' THEN
CASE @sort
WHEN 5 THEN sum(isnull(c.Channel_Visits,0))
WHEN 6 THEN sum(isnull(l.Lib_Visits,0))
WHEN 7 THEN sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0))
WHEN 8 THEN sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0))
END
END
DESC,
CASE lower(@SortType)
WHEN 'asc' THEN
CASE @sort
WHEN 5 THEN sum(isnull(c.Channel_Visits,0))
WHEN 6 THEN sum(isnull(l.Lib_Visits,0))
WHEN 7 THEN sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0))
WHEN 8 THEN sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0))
END
END
END
------------------------------------------ END OF PROCEDURE
SET NOCOUNT OFF
END
September 4, 2007 at 12:46 am
Wow.
OK, I haven't read through all of that, maybe over lunch, but one thing caught my eye
IF
@GroupLevel = 1
BEGIN
-- Do something
END
IF @GroupLevel = 2
BEGIN
-- Do something
END
A stored procedure structured like that, with multiple possible execution branches can end up with execution plans that are optimal for one of the branches and not for the others. A stored proc has a single plan and the first time it compiles, all of the possible execution paths are compiled and optimised, based on the parameters passed for the first execution.
I usually recomend that people split collossal procs like that into smaller procs that can be called from the master proc. Something like this
IF @GroupLevel = 1
BEGIN
EXEC SubProc_1 @params ....
END
IF @GroupLevel = 2
BEGIN
EXEC SubProc_2 @params ....
END
That way each of the sub procs gets its own plan. You can also run the sub procs seperatly to see which is the slow one
p.s. Existing indexes?
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
September 4, 2007 at 5:56 am
Few of procs were already written as you mentioned above like calling sub procedues but it does not produce any desired performance that we say YES, here is the performance gain:
IF @GroupLevel = 1
BEGIN
EXEC SubProc_1 @params ....
END
IF @GroupLevel = 2
BEGIN
EXEC SubProc_2 @params ....
END
The slow one is the one which is retrieving more columns and has more where clauses. You can see the output results and time it takes from following (remarks in proc above).
If I call following proc with parameters it produces 95358 rows in 1:16 mins (1 minute and 16 seconds.
SP_Caller_Usage @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=2, @SortType ='desc', @GroupLevel=1 -- (95358) in 1:16/18 (Administration)
Indexes are usually defined on Primary and Foreing keys for joins. Thats it.
If you think there is any better solution to write where clause and can optimize further then how?
based on all my queries If there is any lake of knowledge that I require let me guide aswell.
Shamshad Ali.
September 4, 2007 at 8:52 am
Is it possible to pre-process the results of the grouped subqueries into separate tables?
Doing aggregate functions on derived tables (themselves having aggregate functions) is implicitly going to be very costly, and the performance usually will *suck*. I'm talknig about these:
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
I don't know how often these stats change, how often they're accessed, or if your users could live with "near-real-time" data, but if you could process those sub-queries into "real tables" with actual live indexes - performance should go up. At least somewhat, since you have a HAVING predicate, and a CASE statement in the order by (I don't think you can avoid them): each of these tend to make this run slower, but having them ALL in there at the same time is going to make this thing churn.
The nice part about the pre-processing, especially if your users can deal with recent data, you can do that in an offline state (meaning, every x hours, instead of when they want to see the report). It will make their report "pop" a lot faster.
If you have disk space to burn/spare - look at doing as much pre-processing as you can. Something like - put the results of your group by , but excluding the HAVING and the ORDER by statements to a table, then run a SELECT * from <myworking table> where <the logic for the HAVING statement> ORDER BY <your ORDER BY statement>.
----------------------------------------------------------------------------------
Your lack of planning does not constitute an emergency on my part...unless you're my manager...or a director and above...or a really loud-spoken end-user..All right - what was my emergency again?
September 4, 2007 at 9:03 am
We can't go on pre-processing (I can't forward this idea to upper management), also there is no specific time for pulling out report. We don't know when and from which location these reports are requested so we can't fix a time for pre-processing. Also the changes in tracking tables (you marked above) are inserted upon site access 24X7.
Shamshad Ali.
September 4, 2007 at 9:33 am
Have you considered indexed views to replace your derived tables? It will result in a slow down of inserts/updates but that trade off may be acceptable considering your reporting needs.
Is session_id indexed in your *_visits tables?
Is there an index on tbl_cv_user.Firstname?
Is there an index on tbl_Tracking_mstr.Start_DateTime.
If not, I would start by adding those, see if it makes any difference. Compare costs as given in the execution plan, rather than time as it's less prone to fluctuations due to server load.
Have a look at the execution plan for the query and identify where the high costs are. Will likely be in scans (table or clustered index), hash aggregates or sorts
Given the branching nature of your proc and the form of the where clauses, there is no way this proc can possibly have a consistent plan. I would recomend, if you can't split it out, mark the procedure to recompile on every execution. At least that way there's no chance of getting a wildly inappropraite plan from the plan cache.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
September 5, 2007 at 7:57 am
I understand not being able to pre-process outside of this procedure, but have you considered just using actual tables that get rebuilt with this data (at the tope of the proc before the 7 IF statements)? meaning - dump the intermediate summaries to actual tables and use the tables in the final report? If nothing else - you might be able to move some of the work out of TempDB, or take advantage of some indexing. You can sometimes achieve substantial gains that way.
----------------------------------------------------------------------------------
Your lack of planning does not constitute an emergency on my part...unless you're my manager...or a director and above...or a really loud-spoken end-user..All right - what was my emergency again?
September 5, 2007 at 9:00 pm
You're simply trying to do too much at once in each section... you must "Divide and Conquer" if you expect to get any performance out of this.
First thing I notice is that the WHERE clauses are all the same... and none of them are capable of using an Index SEEK... the best you can get out of this is an Index SCAN which can be worse than a Table Scan if BookMarks are used.
Since the WHERE clause is what limits the data and the tables involved are the smallest of the lot, start with a simple query to populate a TempTable with the data from all columns used in all SELECTs from the tbl_Tracking_mstr and tbl_cv_user tables based on the criteria in the WHERE clause. BE SURE TO INCLUDE THE SESSIONID, as well. Notice that you must NOT do any aggragation of data for this first step... it'll just slow things down... you're just trying to get a smaller list of things to aggragate when it's time. Notice that this temp table will serve as the basis for ALL the reports...
Next, do your aggragates and populate the temp table with them. These aggragates should be done as updates and in pairs based on the tables that the counts are coming from. You'll be surprised at how fast these run because, guess what?... They'll be able to use indexes on the larger tables and the temp table will be really small!!!!
Last, but not least, do a SELECT/Aggragate on the comparitively small temp table to display the data according to the inputs for sort order and the like. You should only have one of these.
Overall, this will also make maintenance of the code much easier because there will only be 3 main sections to the code instead of all the ones you currently have.
Also, go back and review the criteria in the WHERE clause for logic errors... here's a dandy one I found...
AND m.Administration_ID BETWEEN COALESCE(@Administration_id, Administration_ID) AND COALESCE(@Administration_id, Administration_ID)
... ya wanna tell me why the heck you need a BETWEEN on that??? Think about it!
--Jeff Moden
Change is inevitable... Change for the better is not.
September 13, 2007 at 12:44 am
For the time, after tunning database tables using proper indexing, if there are lots of WHERE and they are dynamic (depends on user's selection) I use dynamic query to solve the problem, those results that were taking 1:30 sec, now comes only in 20 sec.
I'm using block of code which depends in paramters and may vary, some block of code is always static or CASE, so I'm concatinating strings to retrieve final query and it really produces nice results in the sense of performance.
As for Jeff pointed me above BETWEEN clause with same range was unknow to me and i have fixed that too. Thanks.
I'm still not sure that this is a final solutions or still I'm going wrong. I would like comments from all who really faced such situation and produced nice solution in production.
/*****************************************************/
set @SQLString = @SQLString + @WhereString + @GroupByString + @OrderByString
exec sp_executesql @SQLString
/*****************************************************/
Alter proc SP_Visitor_Usage_Dept_3
-- SP_Visitor_Usage_Dept_3 @ToDate = '12-July-2007', @login_ID='VHAAUGSTONER', @FromDate = '01-Jan-2000', @sort=2, @SortType ='desc' -- (95358) in 1:16/18 (Administration)
-- SP_Visitor_Usage_Dept_3 @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=2, @SortType ='desc' -- (95358) in 1:16/18 (Administration)
-- SP_Visitor_Usage_Dept_3 @ToDate = '12-July-2007', @First_Name ='deborah', @FromDate = '01-Jan-2000', @sort=2, @SortType ='desc' -- (95358) in 1:16/18 (Administration)
-- SP_Visitor_Usage_Dept_3 @ToDate = '12-July-2007', @GroupLevel=1, @First_Name ='deborah', @Last_Name ='mar', @FromDate = '01-Jan-2000', @sort=10, @SortType ='desc' -- (95358) in 1:16/18 (Administration)
-- SP_Visitor_Usage @ToDate = '12-July-2007', @FromDate = '11-22-2005', @sort=11, @SortType ='desc', @GroupLevel=4 -- (95358) in 1:16/18 (Administration)
-- SP_Visitor_Usage_Dept_3 @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=2, @SortType ='desc', @GroupLevel=1 -- (95358) in 1:16/18 (Administration)
-- SP_Visitor_Usage_Dept_3 @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=7, @SortType ='desc', @GroupLevel=2 -- (95887) in 1:24/22 (Region)
-- SP_Visitor_Usage_Dept_3 @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=7, @SortType ='desc', @GroupLevel=3 -- (97062) in 1:32/28 (Facility)
-- SP_Visitor_Usage_Dept_3 @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=5, @SortType ='desc', @GroupLevel=4 -- (95271) in 1:10/15 (Department)
-- SP_Visitor_Usage_Dept_3 @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=5, @SortType ='desc', @GroupLevel=5 -- (3) in 0:49 (Administration)
-- SP_Visitor_Usage_Dept_3 @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=5, @SortType ='desc', @GroupLevel=6 -- (34) in 1:22 (Region)
-- SP_Visitor_Usage_Dept_3 @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=5, @SortType ='desc', @GroupLevel=7 -- (216) in 1:42 (Facility)
-- SP_Visitor_Usage_Dept_3 @ToDate = '12-July-2007', @FromDate = '01-Jan-2000', @sort=5, @SortType ='desc', @GroupLevel=8 -- (1) in 0:37 (Department)
@ToDate datetime ,
@FromDate datetime ,
@Last_Name varchar(100)=NULL,
@First_Name varchar(100)=NULL,
@Login_ID varchar(100)=NULL,
@Administration_id smallint=0,
@Region_ID smallint=0,
@Facility_Id smallint=0,
@sort smallint=6,
@SortType varchar(10)='DESC',
@GroupLevel smallint=4
AS
BEGIN
-- SET NOCOUNT ON
set @First_Name = case @First_Name when '' then Null else @First_Name end
set @Last_Name = case @Last_Name when '' then Null else @Last_Name end
SET @Login_ID = case @Login_ID when '' then Null else @Login_ID end
set @Administration_id = case @Administration_id when 0 then Null else @Administration_id end
set @Region_ID = case @Region_ID when 0 then Null else @Region_ID end
set @Facility_Id = case @Facility_Id when 0 then Null else @Facility_Id end
Declare @SQLString varchar(4000), @GroupByString varchar(1000), @WhereString varchar(2000), @OrderByString varchar(1000)
Declare @FinalQueryToRun nvarchar(4000)
----------------------------- group level = 1
IF @GroupLevel = 1
BEGIN
set @SQLString =
'
SELECT m.Login_ID,
m.Administration,
sum(isnull(l.Lib_Visits,0)) as Lib_Visits,
sum(isnull(l.Lib_Completed,0)) as Lib_Completed,
sum(isnull(c.Channel_Visits,0)) as Channel_Visits,
sum(isnull(c.Ch_Prog_Completed,0)) as Ch_Prog_Completed,
sum(isnull(l.Lib_Visits,0)) + sum(isnull(c.Channel_Visits,0)) as tot_Visits,
sum(isnull(l.Lib_Completed,0)) + sum(isnull(c.Ch_Prog_Completed,0)) as tot_Completed,
cv.First_name + ' + ''' ''' + ' + cv.Last_name as Login_Name,
cv.First_name,
cv.Last_name,
cv.Department,
cv.Guest,
m.Login_ID as [User_ID],
m.Login_Type,
m.Guest_ID AS Guest_Exist
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
LEFT OUTER JOIN tbl_cv_user cv ON m.Login_ID = cv.cv_user_name
where
m.Start_DateTime BETWEEN ''' + convert(varchar, @FromDate, 107) + ''' AND ''' + convert(varchar, @ToDate, 107) + '''
'
set @GroupByString =
' GROUP BY
m.Login_ID,
m.Administration,
m.Login_Type,
m.Guest_ID,
cv.First_name,
cv.Last_name,
cv.Department,
cv.Guest
having
sum(isnull(l.Lib_Visits,0)) >0 or
sum(isnull(l.Lib_Completed,0)) >0 or
sum(isnull(c.Channel_Visits,0)) >0 or
sum(isnull(c.Ch_Prog_Completed,0)) >0 '
END
----------------------------- group level = 2
IF @GroupLevel = 2
BEGIN
set @SQLString =
' SELECT m.Login_ID,
m.Administration,
m.Region,
sum(isnull(l.Lib_Visits,0)) as Lib_Visits,
sum(isnull(l.Lib_Completed,0)) as Lib_Completed,
sum(isnull(c.Channel_Visits,0)) as Channel_Visits,
sum(isnull(c.Ch_Prog_Completed,0)) as Ch_Prog_Completed,
sum(isnull(l.Lib_Visits,0)) + sum(isnull(c.Channel_Visits,0)) as tot_Visits,
sum(isnull(l.Lib_Completed,0)) + sum(isnull(c.Ch_Prog_Completed,0)) as tot_Completed,
cv.First_name + ' + ''' ''' + ' + cv.Last_name as Login_Name,
cv.First_name,
cv.Last_name,
cv.Department,
cv.Guest,
m.Login_ID as [User_ID],
m.Login_Type,
m.Guest_ID AS Guest_Exist
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
LEFT OUTER JOIN tbl_cv_user cv ON m.Login_ID = cv.cv_user_name
where
m.Start_DateTime BETWEEN ''' + convert(varchar, @FromDate, 107) + ''' AND ''' + convert(varchar, @ToDate, 107) + '''
'
set @GroupByString =
' GROUP BY
m.Login_ID,
m.Administration,
m.Region,
m.Login_Type,
m.Guest_ID,
cv.First_name,
cv.Last_name,
cv.Department,
cv.Guest
having
sum(isnull(l.Lib_Visits,0)) >0 or
sum(isnull(l.Lib_Completed,0)) >0 or
sum(isnull(c.Channel_Visits,0)) >0 or
sum(isnull(c.Ch_Prog_Completed,0)) >0 '
END
----------------------------- group level = 3
IF @GroupLevel = 3
BEGIN
set @SQLString =
' SELECT m.Login_ID,
m.Administration,
m.Region,
m.Facility,
sum(isnull(l.Lib_Visits,0)) as Lib_Visits,
sum(isnull(l.Lib_Completed,0)) as Lib_Completed,
sum(isnull(c.Channel_Visits,0)) as Channel_Visits,
sum(isnull(c.Ch_Prog_Completed,0)) as Ch_Prog_Completed,
sum(isnull(l.Lib_Visits,0)) + sum(isnull(c.Channel_Visits,0)) as tot_Visits,
sum(isnull(l.Lib_Completed,0)) + sum(isnull(c.Ch_Prog_Completed,0)) as tot_Completed,
cv.First_name + ' + ''' ''' + ' + cv.Last_name as Login_Name,
cv.First_name,
cv.Last_name,
cv.Department,
cv.Guest,
m.Login_ID as [User_ID],
m.Login_Type,
m.Guest_ID AS Guest_Exist
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
LEFT OUTER JOIN tbl_cv_user cv ON m.Login_ID = cv.cv_user_name
where
m.Start_DateTime BETWEEN ''' + convert(varchar, @FromDate, 107) + ''' AND ''' + convert(varchar, @ToDate, 107) + '''
'
set @GroupByString =
' GROUP BY
m.Login_ID,
m.Administration,
m.Region,
m.Facility,
m.Login_Type,
m.Guest_ID,
cv.First_name,
cv.Last_name,
cv.Department,
cv.Guest
having
sum(isnull(l.Lib_Visits,0)) >0 or
sum(isnull(l.Lib_Completed,0)) >0 or
sum(isnull(c.Channel_Visits,0)) >0 or
sum(isnull(c.Ch_Prog_Completed,0)) >0 '
END
----------------------------- group level = 4
IF @GroupLevel = 4
BEGIN
set @SQLString =
'
SELECT m.Login_ID,
sum(isnull(l.Lib_Visits,0)) as Lib_Visits,
sum(isnull(l.Lib_Completed,0)) as Lib_Completed,
sum(isnull(c.Channel_Visits,0)) as Channel_Visits,
sum(isnull(c.Ch_Prog_Completed,0)) as Ch_Prog_Completed,
sum(isnull(l.Lib_Visits,0)) + sum(isnull(c.Channel_Visits,0)) as tot_Visits,
sum(isnull(l.Lib_Completed,0)) + sum(isnull(c.Ch_Prog_Completed,0)) as tot_Completed,
cv.First_name + ' + ''' ''' + ' + cv.Last_name as Login_Name,
cv.First_name,
cv.Last_name,
cv.Department,
cv.Guest,
m.Login_ID as [User_ID],
m.Login_Type,
m.Guest_ID AS Guest_Exist
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
LEFT OUTER JOIN tbl_cv_user cv ON m.Login_ID = cv.cv_user_name
where
m.Start_DateTime BETWEEN ''' + convert(varchar, @FromDate, 107) + ''' AND ''' + convert(varchar, @ToDate, 107) + '''
'
set @GroupByString =
' GROUP BY
m.Login_ID,
m.Login_Type,
m.Guest_ID,
cv.First_name,
cv.Last_name,
cv.Department,
cv.Guest
having
sum(isnull(l.Lib_Visits,0)) >0 or
sum(isnull(l.Lib_Completed,0)) >0 or
sum(isnull(c.Channel_Visits,0)) >0 or
sum(isnull(c.Ch_Prog_Completed,0)) >0 '
END
----------------------------- group level = 5
IF @GroupLevel = 5
BEGIN
set @SQLString =
'SELECT m.Administration_ID,
Administration,
sum(isnull(l.Lib_Visits,0)) as Lib_Visits,
sum(isnull(l.Lib_Completed,0)) as Lib_Completed,
sum(isnull(c.Channel_Visits,0)) as Channel_Visits,
sum(isnull(c.Ch_Prog_Completed,0)) as Ch_Prog_Completed,
sum(isnull(l.Lib_Visits,0)) + sum(isnull(c.Channel_Visits,0)) as tot_Visits,
sum(isnull(l.Lib_Completed,0)) + sum(isnull(c.Ch_Prog_Completed,0)) as tot_Completed
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
where
m.Start_DateTime BETWEEN ''' + convert(varchar, @FromDate, 107) + ''' AND ''' + convert(varchar, @ToDate, 107) + '''
'
set @GroupByString =
' GROUP BY
m.Administration_ID,
Administration
having
sum(isnull(l.Lib_Visits,0)) >0 or
sum(isnull(l.Lib_Completed,0)) >0 or
sum(isnull(c.Channel_Visits,0)) >0 or
sum(isnull(c.Ch_Prog_Completed,0)) >0 '
END
----------------------------- group level = 6
IF @GroupLevel = 6
BEGIN
set @SQLString =
' SELECT m.Administration_ID,
Administration,
m.Region_ID,
m.Region,
sum(isnull(l.Lib_Visits,0)) as Lib_Visits,
sum(isnull(l.Lib_Completed,0)) as Lib_Completed,
sum(isnull(c.Channel_Visits,0)) as Channel_Visits,
sum(isnull(c.Ch_Prog_Completed,0)) as Ch_Prog_Completed,
sum(isnull(l.Lib_Visits,0)) + sum(isnull(c.Channel_Visits,0)) as tot_Visits,
sum(isnull(l.Lib_Completed,0)) + sum(isnull(c.Ch_Prog_Completed,0)) as tot_Completed
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
where
m.Start_DateTime BETWEEN ''' + convert(varchar, @FromDate, 107) + ''' AND ''' + convert(varchar, @ToDate, 107) + '''
'
set @GroupByString =
' GROUP BY
m.Administration_ID,
Administration,
m.Region_ID,
m.Region
having
sum(isnull(l.Lib_Visits,0)) >0 or
sum(isnull(l.Lib_Completed,0)) >0 or
sum(isnull(c.Channel_Visits,0)) >0 or
sum(isnull(c.Ch_Prog_Completed,0)) >0 '
END
----------------------------- group level = 7
IF @GroupLevel = 7
BEGIN
set @SQLString =
' SELECT m.Administration_ID,
Administration,
m.Region_ID,
m.Region,
m.Facility_ID,
m.Facility,
sum(isnull(l.Lib_Visits,0)) as Lib_Visits,
sum(isnull(l.Lib_Completed,0)) as Lib_Completed,
sum(isnull(c.Channel_Visits,0)) as Channel_Visits,
sum(isnull(c.Ch_Prog_Completed,0)) as Ch_Prog_Completed,
sum(isnull(l.Lib_Visits,0)) + sum(isnull(c.Channel_Visits,0)) as tot_Visits,
sum(isnull(l.Lib_Completed,0)) + sum(isnull(c.Ch_Prog_Completed,0)) as tot_Completed
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
where
m.Start_DateTime BETWEEN ''' + convert(varchar, @FromDate, 107) + ''' AND ''' + convert(varchar, @ToDate, 107) + '''
'
set @GroupByString =
' GROUP BY
m.Administration_ID,
Administration,
m.Region_ID,
m.Region,
m.Facility_ID,
m.Facility
having
sum(isnull(l.Lib_Visits,0)) >0 or
sum(isnull(l.Lib_Completed,0)) >0 or
sum(isnull(c.Channel_Visits,0)) >0 or
sum(isnull(c.Ch_Prog_Completed,0)) >0 '
END
----------------------------- group level = 8
IF @GroupLevel = 8
BEGIN
set @SQLString =
' SELECT
sum(isnull(l.Lib_Visits,0)) as Lib_Visits,
sum(isnull(l.Lib_Completed,0)) as Lib_Completed,
sum(isnull(c.Channel_Visits,0)) as Channel_Visits,
sum(isnull(c.Ch_Prog_Completed,0)) as Ch_Prog_Completed,
sum(isnull(l.Lib_Visits,0)) + sum(isnull(c.Channel_Visits,0)) as tot_Visits,
sum(isnull(l.Lib_Completed,0)) + sum(isnull(c.Ch_Prog_Completed,0)) as tot_Completed
FROM tbl_Tracking_mstr m
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Lib_Visits,
SUM(completed) AS Lib_Completed FROM tbl_Tracking_Library_Content group by session_ID
) l ON l.Session_Id = m.Session_Id
left JOIN
(
SELECT session_id, COUNT(Session_Id) AS Channel_Visits,
SUM(completed) AS Ch_Prog_Completed FROM tbl_Tracking_Channel_Program group by session_ID
) c ON c.Session_Id = m.Session_Id
where
m.Start_DateTime BETWEEN ''' + convert(varchar, @FromDate, 107) + ''' AND ''' + convert(varchar, @ToDate, 107) + '''
'
set @GroupByString =
' having
sum(isnull(l.Lib_Visits,0)) >0 or
sum(isnull(l.Lib_Completed,0)) >0 or
sum(isnull(c.Channel_Visits,0)) >0 or
sum(isnull(c.Ch_Prog_Completed,0)) >0 '
END
------------------------------------- where case
set @WhereString = ' '
if @First_Name <> '' or @First_Name is NOT NULL
Begin
set @First_Name = @First_Name + '%'
set @WhereString = @WhereString + ' AND m.Login_Name LIKE ''' + @First_Name + ''''
end
if @Last_Name <> '' or @Last_Name is NOT NULL
Begin
set @Last_Name = '% ' + @Last_Name + '%'
set @WhereString = @WhereString + ' AND m.Login_Name LIKE ''' + @Last_Name + ''''
end
if @Login_ID <> '' or @Login_ID is NOT NULL
Begin
set @Login_ID = @Login_ID + '%'
set @WhereString = @WhereString + ' AND m.Login_ID LIKE ''' + @Login_ID + ''''
end
if @Administration_id <> '' or @Administration_id is NOT NULL
set @WhereString = @WhereString + ' AND m.Administration_ID = ' + convert(varchar, @Administration_id) + ''
if @Region_ID <> '' or @Region_ID is NOT NULL
set @WhereString = @WhereString + ' AND m.Region_ID = ' + convert(varchar, @Region_ID ) + ''
if @Facility_ID <> '' or @Facility_ID is NOT NULL
set @WhereString = @WhereString + ' AND m.Facility_ID = ' + convert(varchar, @Facility_ID) + ''
-------------------------------- Order by
set @OrderByString = 'ORDER BY '
IF @sort = 1
set @OrderByString = @OrderByString + 'Login_Id'
else if @sort = 2
set @OrderByString = @OrderByString + 'Administration'
else if @sort = 3
set @OrderByString = @OrderByString + 'Region'
else if @sort = 4
set @OrderByString = @OrderByString + 'Facility'
else if @sort = 9
set @OrderByString = @OrderByString + 'Login_ID'
else if @sort = 10
set @OrderByString = @OrderByString + 'Department'
else if @sort = 11
set @OrderByString = @OrderByString + 'Guest_ID'
else if @sort = 5
set @OrderByString = @OrderByString + 'sum(isnull(c.Channel_Visits,0))'
else if @sort = 6
set @OrderByString = @OrderByString + 'sum(isnull(l.Lib_Visits,0)) '
else if @sort = 7
set @OrderByString = @OrderByString + 'sum(isnull(l.Lib_Visits,0))+ sum(isnull(c.Channel_Visits,0)) '
else if @sort = 8
set @OrderByString = @OrderByString + 'sum(isnull(l.Lib_Completed,0))+ sum(isnull(c.Ch_Prog_Completed,0)) '
if @SortType = 'DESC'
set @OrderByString = @OrderByString + ' DESC'
else
set @OrderByString = @OrderByString + ' ASC'
set @SQLString = @SQLString + @WhereString + @GroupByString + @OrderByString
-- print @SQLString
-- set @FinalQueryToRun = @SQLString
-- print @FinalQueryToRun
exec sp_executesql @SQLString
END
/*****************************************************/
Shamshad Ali
September 14, 2007 at 6:50 am
It was mentioned that you can't pre-calc the data. Actually have you considered using temp tables for this. Most of the subqueries were group by's That would be perfect to insert into a temp table with a PK on the group by fields. (session id). The cost is the temp table, but I am sure you are using temp anyways. Advantage is that you will now be joining to an indexed table (the inline view probably is not).
I have recently had to do something very similar. 400M rows of data spread across 3 tables with an 8 table join to get the end result. I basically do the 5 table part first and write the results to a temp table. That is then joined to the 3 big tables to get me my final result. Worst case still takes 20min to run, but most are more like the 20 second variety.
Viewing 15 posts - 1 through 15 (of 25 total)
You must be logged in to reply to this topic. Login to reply