Мне нужна помощь с оптимизацией следующего запроса.
Моя проблема
Я пытаюсь очистить таблицу на основе параметра size . (удалить x Мб из этой таблицы) .Я подумал, как реализовать его: перебрать таблицу, начиная с самой старой записи, получить каждый размер строки (я учитываю только столбцы BLOB-объектов), перебрать все связанные таблицы и выполнить для них ту же операцию;if currentSize >= size
остановите запрос и верните список GUIDs
найден
Обратите внимание, что это часть более крупного запроса, поэтому в конце мне нужен список идентификаторов.
То, что я пробовал
Сначала я попытался написать его, используя EntityFramework
, но его выполнение заняло слишком много времени, и я только наполовину закончил его.Поэтому я написал это прямо в T-SQL
.
Вот что мне удалось написать.Однако при работе с базой данных SQL Azure создается исключение тайм-аута.Я знаю, что это связано с ограничением DTU, но мне также интересно, можно ли улучшить этот запрос.Я не эксперт по SQL, и мне нужна ваша помощь.
Текущий запрос
DECLARE @maxSize int = 1
DECLARE @tempTable TABLE
(
Id uniqueidentifier,
Size float,
Position int
)
DECLARE @currentId uniqueidentifier
DECLARE @maxIterations int
DECLARE @index int = 1
SET @maxIterations = (SELECT COUNT(Id) FROM WhereToDelete)
WHILE(@index < @maxIterations)
BEGIN
INSERT INTO @tempTable
SELECT MasterJobGUID, ISNULL(DATALENGTH(BlobColumn1),0) +
ISNULL(DATALENGTH(BlobColumn2),0) +
ISNULL(DATALENGTH(BlobColumn3),0) +
ISNULL(DATALENGTH(BlobColumn4),0),
@index
FROM WhereToDelete
ORDER BY SomeColumn
OFFSET @index ROWS
FETCH NEXT 1 ROWS ONLY
SET @index=@index+1
SET @currentid = (SELECT TOP 1 Id FROM @tempTable ORDER BY Position DESC)
UPDATE @tempTable
SET Size = Size + ( SELECT SUM(ISNULL(DATALENGTH(BlobColumn),0))
FROM LinkedTable
WHERE ParentId = @currentId )
UPDATE @tempTable
SET Size = Size + ( SELECT ISNULL(SUM(ISNULL(DATALENGTH(OtherBlobColumn),0)),0)
FROM OtherLinkedTable
WHERE OtherLinkedTableId IN
(
SELECT OtherLinkedTableId FROM SomeTable
WHERE SomeTableId IN
(
SELECT SomeTableId FROM SomeOtherTable
WHERE ParentId = @currentId
)
))
IF ((SELECT SUM(Size) FROM @tempTable) >= @maxSize*1000000)
BEGIN
BREAK;
END
END
SELECT Id from @tempTable