Эй, у меня есть следующая хранимая процедура, которая работает пошагово
- Выборка всех пользователей, которая не занимает много времени
- Затем выполните цикл по всем пользователям и проверьте, сколько шагов онизавершено в тесте
Это второй шаг, который, кажется, занимает много времени, потому что для каждого пользователя я выполняю запрос на выборку для довольно большой таблицы.
С точки зрения размера Существуетоколо 4000 пользователей и 90000 строк в моей истории tblUserQuestionnaire.
Heres SP
ALTER PROCEDURE [spGetStoreTrainingSummary_Test]
(
@staffId INT = default,
@storeTypeId INT = default,
@storeId INT = default,
@county VARCHAR(50) = default,
@programmeId INT = default,
@profileId INT = default,
@showNulls INT = default,
@position VARCHAR(50) = default,
@roaId INT = default
)
AS
BEGIN
SET NOCOUNT ON;
-- Place all users inner join stores into a temp table
CREATE TABLE #TempMainTable(
[id] INT,
[profileId] INT,
[position] VARCHAR(50),
[storeId] INT,
[county] VARCHAR(50),
[storeTypeId] INT,
[roaId] INT
)
INSERT #TempMainTable
SELECT tblUsers.id, tblUsers.profileId, tblUsers.position, tblStores.id as storeId, tblStores.county, tblStores.storeTypeId, tblStores.roaID
FROM tblUsers INNER JOIN tblStores ON tblUsers.storeId = tblStores.id
WHERE (tblUsers.statusId = 1) AND (tblStores.statusId = 1)
IF @profileId > 0 --## Filter by profile
BEGIN
DELETE FROM #TempMainTable WHERE profileId <> @profileId
END
IF len(@position) > 0 --## Filter by position
BEGIN
DELETE FROM #TempMainTable WHERE position <> @position
END
IF @storeId > 0 --## Filter by store
BEGIN
DELETE FROM #TempMainTable WHERE storeId <> @storeId
END
IF len(@county) > 0 --## Filter by county
BEGIN
DELETE FROM #TempMainTable WHERE county <> @county
END
IF @storeTypeId > 0 --## Filter by storeTypeId
BEGIN
DELETE FROM #TempMainTable WHERE storeTypeId <> @storeTypeId
END
IF @roaId > 0 --## Filter by roaId
BEGIN
DELETE FROM #TempMainTable WHERE roaId <> @roaId
END
-- SELECT * FROM #TempMainTable
CREATE TABLE #TempTable(
[userId] INT,
[menuName] varchar(250),
[stepId] int,
[programmeId] int,
[result] varchar(250)
)
DECLARE @UserId INT
DECLARE @MaxStep INT
DECLARE @Result VARCHAR(100)
DECLARE @UserList CURSOR
SET @UserList = CURSOR FOR
SELECT id
FROM #TempMainTable
GROUP BY id
OPEN @UserList
FETCH NEXT FROM @UserList INTO @UserId
WHILE (@@FETCH_STATUS = 0)
BEGIN
--## Staff Induction Programme
SET @MaxStep = (SELECT MAX(stepId) AS maxId FROM tblUserQuestionnaireHistory WHERE (userId = @UserId) AND (programmeId = 13) AND (success = 1))
SET @Result = (SELECT CASE WHEN @MaxStep = 9 THEN 'Passed' WHEN @MaxStep <> 9 THEN 'Step ' + + CAST(@MaxStep AS VARCHAR(10)) + ' completed out of 9' ELSE 'No steps completed yet' END as Result)
INSERT #TempTable
SELECT @UserId, 'Staff Induction Programme ©', @MaxStep, 13, @Result
--PRINT @UserId
--PRINT @MaxStep
--PRINT @Result
FETCH NEXT FROM @UserList INTO @UserId
END
CLOSE @UserList
DEALLOCATE @UserList
DROP TABLE #TempMainTable
--## Filter by programme id
IF @programmeId IS NOT NULL
BEGIN
DELETE FROM #TempTable WHERE programmeId <> @programmeId
END
IF @showNulls = 1 -- Select All Records
BEGIN
SELECT #TempTable.*, tblUsers.firstName + ' ' + tblUsers.lastName AS fullname, tblUsers.firstName, tblUsers.lastName, tblStores.name AS storeName, tblStores.county, tblStore_Types.name AS storeType, tblUsers.position, tblStores.surname + ' ' + tblStores.name as retailerName, tblProfiles.name as profile, tblRoa.lastname + ' ' + tblRoa.firstname as roa
FROM #TempTable INNER JOIN tblUsers ON #TempTable.userId = tblUsers.id INNER JOIN tblStores ON tblUsers.storeId = tblStores.id INNER JOIN tblStore_Types ON tblStores.storeTypeId = tblStore_Types.id INNER JOIN tblProfiles ON tblUsers.profileId = tblProfiles.id INNER JOIN tblROA ON tblStores.roaID = tblROA.id
END
ELSE IF @showNulls = 2 -- Select Users who have sat at least one training
BEGIN
SELECT #TempTable.*, tblUsers.firstName + ' ' + tblUsers.lastName AS fullname, tblUsers.firstName, tblUsers.lastName, tblStores.name AS storeName, tblStores.county, tblStore_Types.name AS storeType, tblUsers.position, tblStores.surname + ' ' + tblStores.name as retailerName, tblProfiles.name as profile, tblRoa.lastname + ' ' + tblRoa.firstname as roa
FROM #TempTable INNER JOIN tblUsers ON #TempTable.userId = tblUsers.id INNER JOIN tblStores ON tblUsers.storeId = tblStores.id INNER JOIN tblStore_Types ON tblStores.storeTypeId = tblStore_Types.id INNER JOIN tblProfiles ON tblUsers.profileId = tblProfiles.id INNER JOIN tblROA ON tblStores.roaID = tblROA.id
WHERE userId IN (SELECT userId FROM #TempTable WHERE (stepId IS NOT NULL) GROUP BY userId)
END
ELSE -- Select Only Training records that have been sat
BEGIN
SELECT #TempTable.*, tblUsers.firstName + ' ' + tblUsers.lastName AS fullname, tblUsers.firstName, tblUsers.lastName, tblStores.name AS storeName, tblStores.county, tblStore_Types.name AS storeType, tblUsers.position, tblStores.surname + ' ' + tblStores.name as retailerName, tblProfiles.name as profile, tblRoa.lastname + ' ' + tblRoa.firstname as roa
FROM #TempTable INNER JOIN tblUsers ON #TempTable.userId = tblUsers.id INNER JOIN tblStores ON tblUsers.storeId = tblStores.id INNER JOIN tblStore_Types ON tblStores.storeTypeId = tblStore_Types.id INNER JOIN tblProfiles ON tblUsers.profileId = tblProfiles.id INNER JOIN tblROA ON tblStores.roaID = tblROA.id
WHERE (stepId IS NOT NULL)
END
END
Любые советы о том, как я могу утвердить эту хранимую процедуру?
ПРАВКА ПОКАЗАТЬ ПОСЛЕДНЮЮ SP:
ALTER PROCEDURE [u1017987_dbase_user].[spGetStoreTrainingSummary_Test]
(
@staffId INT = default,
@storeTypeId INT = default,
@storeId INT = default,
@county VARCHAR(50) = default,
@programmeId INT = default,
@profileId INT = default,
@showNulls INT = default,
@position VARCHAR(50) = default,
@roaId INT = default
)
AS
BEGIN
SET NOCOUNT ON;
-- Place all users inner join stores into a temp table
CREATE TABLE #TempMainTable(
[id] INT,
[profileId] INT,
[position] VARCHAR(50),
[storeId] INT,
[county] VARCHAR(50),
[storeTypeId] INT,
[roaId] INT
)
CREATE TABLE #TempTable(
[userId] INT,
[menuName] varchar(250),
[stepId] int,
[programmeId] int,
[result] varchar(250)
)
DECLARE @UserId INT
DECLARE @MaxStep INT
DECLARE @Result VARCHAR(100)
DECLARE @UserList CURSOR
;WITH tempMainTable
AS
(
SELECT tblUsers.id, tblUsers.profileId, tblUsers.position, tblStores.id as storeId,
tblStores.county, tblStores.storeTypeId, tblStores.roaID
FROM tblUsers INNER JOIN tblStores ON tblUsers.storeId = tblStores.id
WHERE (tblUsers.statusId = 1) AND (tblStores.statusId = 1)
AND (@profileId = 0 OR profileId = @profileId)
AND (len(@position) = 0 OR position = @position)
AND (@storeId = 0 OR storeId = @storeId)
AND (len(@county) = 0 OR county = @county)
AND (@storeTypeId = 0 OR storeTypeId = @storeTypeId)
AND (@roaId = 0 OR roaId = @roaId)
),
tempTable AS
(
SELECT tempMainTable.userId,
'Staff Induction Programme ©',
(SELECT MAX(stepId) AS maxId FROM tblUserQuestionnaireHistory WHERE (userId = tempMainTable.userId) AND (programmeId = 13) AND (success = 1)),
13,
(SELECT CASE (SELECT MAX(stepId) AS maxId FROM tblUserQuestionnaireHistory WHERE (userId = tempMainTable.userId) AND (programmeId = 13) AND (success = 1)) WHEN 9 THEN 'Passed' ELSE 'Step ' + + CAST(@MaxStep AS VARCHAR(10)) + ' completed out of 9' END as Result)
FROM tempMainTable
WHERE (@programmeId IS NULL OR @programmeId=13)
)
--## Filter by programme id
IF @programmeId IS NOT NULL
BEGIN
DELETE FROM #TempTable WHERE programmeId <> @programmeId
END
IF @showNulls = 1 -- Select All Records
BEGIN
SELECT #TempTable.*, tblUsers.firstName + ' ' + tblUsers.lastName AS fullname, tblUsers.firstName, tblUsers.lastName, tblStores.name AS storeName, tblStores.county, tblStore_Types.name AS storeType, tblUsers.position, tblStores.surname + ' ' + tblStores.name as retailerName, tblProfiles.name as profile, tblRoa.lastname + ' ' + tblRoa.firstname as roa
FROM #TempTable INNER JOIN tblUsers ON #TempTable.userId = tblUsers.id INNER JOIN tblStores ON tblUsers.storeId = tblStores.id INNER JOIN tblStore_Types ON tblStores.storeTypeId = tblStore_Types.id INNER JOIN tblProfiles ON tblUsers.profileId = tblProfiles.id INNER JOIN tblROA ON tblStores.roaID = tblROA.id
END
ELSE IF @showNulls = 2 -- Select Users who have sat at least one training
BEGIN
SELECT #TempTable.*, tblUsers.firstName + ' ' + tblUsers.lastName AS fullname, tblUsers.firstName, tblUsers.lastName, tblStores.name AS storeName, tblStores.county, tblStore_Types.name AS storeType, tblUsers.position, tblStores.surname + ' ' + tblStores.name as retailerName, tblProfiles.name as profile, tblRoa.lastname + ' ' + tblRoa.firstname as roa
FROM #TempTable INNER JOIN tblUsers ON #TempTable.userId = tblUsers.id INNER JOIN tblStores ON tblUsers.storeId = tblStores.id INNER JOIN tblStore_Types ON tblStores.storeTypeId = tblStore_Types.id INNER JOIN tblProfiles ON tblUsers.profileId = tblProfiles.id INNER JOIN tblROA ON tblStores.roaID = tblROA.id
WHERE userId IN (SELECT userId FROM #TempTable WHERE (stepId IS NOT NULL) GROUP BY userId)
END
ELSE -- Select Only Training records that have been sat
BEGIN
SELECT #TempTable.*, tblUsers.firstName + ' ' + tblUsers.lastName AS fullname, tblUsers.firstName, tblUsers.lastName, tblStores.name AS storeName, tblStores.county, tblStore_Types.name AS storeType, tblUsers.position, tblStores.surname + ' ' + tblStores.name as retailerName, tblProfiles.name as profile, tblRoa.lastname + ' ' + tblRoa.firstname as roa
FROM #TempTable INNER JOIN tblUsers ON #TempTable.userId = tblUsers.id INNER JOIN tblStores ON tblUsers.storeId = tblStores.id INNER JOIN tblStore_Types ON tblStores.storeTypeId = tblStore_Types.id INNER JOIN tblProfiles ON tblUsers.profileId = tblProfiles.id INNER JOIN tblROA ON tblStores.roaID = tblROA.id
WHERE (stepId IS NOT NULL)
END
END