Как повысить производительность запросов SQL Server

#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] 
....