У меня есть таблица, которая выглядит, как этотПочему мой коррелированный подзапрос никогда не заканчивается?
Каталог NVARCHAR (макс)
Extension NVARCHAR (10)
Длина BIGINT
У меня также есть другая таблица, которая обеспечивает тип файла (таблицы перекодировки)
расширение NVARCHAR (10)
FileType NVARCHAR (50)
Это сказанное у меня есть связанный подзапрос я хотел перейти на sproc, который принимает в уровни от корня и возвращает вам каталоги и их типы файлов на определенном уровне. В основной таблице около 400 тыс. Строк и около 800 расширений в таблице поиска.
Запрос заключается в следующем:
declare @levelsFromRoot as int = 7
--declare @auditName as varchar(max) = 'Aetna'
select
ef.Type,
sf.Directory,
(select count(distinct part)
FROM dbo.vwAuditView
cross APPLY dbo.SplitPath(substring([Directory],1,LEN([Directory])
-CHARINDEX('\',REVERSE([Directory]))) ,'\') AS Results
where Directory = sf.Directory) as [LevelsFromRoot]
from dbo.FS02V_SourceFiles sf
inner join dbo.ExtensionFix ef
on sf.Extension = ef.Extension
Where (select count(distinct part)
FROM dbo.vwAuditView
cross APPLY dbo.SplitPath(substring([Directory],1,LEN([Directory])
-CHARINDEX('\',REVERSE([Directory]))) ,'\') AS Results
where Directory = sf.Directory) = @levelsFromRoot
order by Directory asc
Поперечное сечение применяется в подзапрос подсчитывает уровни в каждом пути, начиная от корня. вы должны уметь передавать количество уровней из корня и передавать список каталогов на этом уровне и соответствующие им типы файлов. Этот запрос уже работает 25 минут. Он возвращает мне данные. Есть ли что-то, что я могу сделать, чтобы улучшить это? Я довольно новичок в коррелированных подзапросах и цифре. Я делаю что-то не так.
Для ясности вид выглядит следующим образом:
select Directory
--, ef.Extension
, ef.Type
, sum(Length) as [Size - Bytes]
from dbo.FS02V_SourceFiles sf
INNER JOIN dbo.ExtensionFix ef
on sf.Extension = ef.Extension
group by ef.type, Directory
Функция:
ALTER FUNCTION [dbo].[CHARINDEX2]
(
@TargetStr varchar(8000),
@SearchedStr varchar(8000),
@Occurrence int
)
RETURNS int
AS
BEGIN
DECLARE @pos INT, @counter INT, @ret INT
set @pos = CHARINDEX(@TargetStr, @SearchedStr)
set @counter = 1
if @Occurrence = 1 set @ret = @pos
else
begin
while (@counter < @Occurrence)
begin
select @ret = CHARINDEX(@TargetStr, @SearchedStr, @pos + 1)
set @counter = @counter + 1
set @pos = @ret
end
end
RETURN @ret
Как выглядит ваша функция разделения? Есть ли там петли или курсоры? Как насчет представления? Я подозреваю, что проблема на самом деле не является коррелированным подзапросом, а потому, что функция split не является хорошей и вы вызываете несколько раз. –
@SeanLange - я обновил исходный ответ с помощью определения функции. Да, там есть цикл while. Я не писал запрос, но он делал именно то, что мне нужно. Я хотел передать ему строку типа «C: \ Foo \ Bar» и вернуть ее, сколько уровней из корня - IE 2 - другой пример «C: \ Foo \ Bar \ Another» возвращает 3. Но он также должен разделите строку, если я решил использовать данные таким образом. – VinnyGuitara
Этот сплиттер, скорее всего, является корнем вашей проблемы. Вы должны рассмотреть возможность замены этого с помощью разделителя на основе набора. Вот много отличных примеров. http://sqlperformance.com/2012/07/t-sql-queries/split-strings –