#sql #sql-server #tsql #sql-server-2016 #database-performance
#sql #sql-сервер #tsql #sql-server-2016 #база данных-производительность
Вопрос:
У меня есть временная таблица внутри моей процедуры, которая соединяется с другой временной таблицей, и, похоже, для ее запуска требуется некоторое время. Кто-нибудь может предложить, как ускорить это.
Ниже приведен мой фрагмент кода:
declare @installs table
(
UserName varchar(200),
DeviceName varchar(500),
FirstSeenDate datetime
)
insert into @installs
SELECT [Username]
,[Device Name]
,min([First Seen]) as 'Install Date'
FROM [DataCollection].[dbo].[iBoss_Installed_Users]
where [Device Type] not like '%Server%'
group by [Device Name], Username
declare @installs_User table
(
UserName varchar(200),
InstalledDate varchar(max)
)
insert into @installs_User
select main.UserName,
left(main.installs,len(main.installs)-1) as "Installs"
From
(
select distinct ins2.UserName,
(
select convert(varchar(200),ins.FirstSeenDate) ', ' as [text()]
from @installs ins
where ins.UserName=ins2.UserName
order by ins.Username
for XML PATH('')
) [installs]
from @installs ins2
)[Main]
Комментарии:
1. можете ли вы показать таблицы, может быть, будет легче понять, что вы пытаетесь сделать.
2. Для вопросов, связанных с производительностью, нам нужен план выполнения, который вы можете предоставить с помощью «Вставить план».
3. @ Dale K кажется, что мой XML-ПУТЬ («) требует времени. Есть ли какая-либо альтернатива для этого
4. Это действительно для SQL Server 2008?
5. @MatBailie , Нет. Я использую sql server 2016
Ответ №1:
Я бы не стал использовать табличную переменную или временную таблицу, а вместо этого использовал бы общее табличное выражение. Я бы также использовал GROUP BY
вместо DISTINCT
, чтобы оптимизатор знал, что ему не нужно пытаться удалить дублирование вашего списка дат…
declare @installs_User table
(
UserName varchar(200),
InstalledDate varchar(max)
);
WITH
installs AS
(
SELECT [Username]
,[Device Name]
,min([First Seen]) as 'Install Date'
FROM [DataCollection].[dbo].[iBoss_Installed_Users]
where [Device Type] not like '%Server%'
group by [Device Name], Username
)
insert into
@installs_User
SELECT main.UserName
,left(main.installs,len(main.installs)-1) as "Installs"
From
(
SELECT
ins2.UserName,
(
select convert(varchar(200),ins.FirstSeenDate) ', ' as [text()]
from installs ins
where ins.UserName=ins2.UserName
order by ins.Username
for XML PATH('')
) [installs]
FROM
installs ins2
GROUP BY
ins2.UserName
)
[Main]
Комментарии:
1. Привет @matbailie . Спасибо за ваш ответ. Но похоже, что подход, который вы дали, занимает больше времени, чем у меня
2. @ram: Пожалуйста, ответьте на комментарий Далека и включите план выполнения в свой вопрос? Используя этот веб-сайт или аналогичный; brentozar.com/pastetheplan (Я предполагаю, что ваша исходная таблица не имеет адекватной индексации.)
Ответ №2:
Во-первых, это не временные таблицы, это табличные переменные, и SQL Server имеет для них жестко запрограммированную статику, поэтому оценка всегда далека от истины, и они отстой в этом вопросе.
Так что, если вы просто используете вместо этого временную таблицу и (возможно, добавите к ним индекс), это очень поможет:
create table #installs
(
UserName varchar(200),
DeviceName varchar(500),
FirstSeenDate datetime
)
insert into #installs
SELECT [Username]
....